z = z - relax * (2*fz*f1z) / (2*f1z^2 - fz*f2z) + seed;
}
bool bailout(void)
{
return(|z - zold| > bailout);
}
void description(void)
{
this.title = "DoubleHalleyNova (Julia)";
this.helpfile = "dmj-pub\dmj-pub-uf-dhn.htm";
this.maxiter = 1000;
this.periodicity = 0;
this.center = (0,0);
this.magn = 1.5;
seed.caption = "Julia Seed";
seed.default = (0,0);
seed.hint = "This is the Julia seed, a constant parameter which defines the shape of the fractal.";
power1.caption = "Primary Exponent";
power1.default = (4,0);
power1.hint = "Defines the primary exponent for the equation.";
power2.caption = "Secondary Exponent";
power2.default = (2,0);
power2.hint = "Defines the secondary exponent for the equation.";
coeff1.caption = "Primary Scale";
coeff1.default = (1,0);
coeff1.hint = "Defines the coefficient (multiplier) for the primary exponent term.";
coeff2.caption = "Secondary Scale";
coeff2.default = (-2,0);
coeff2.hint = "Defines the coefficient (multiplier) for the secondary exponent term.";
bailout.caption = "Bailout";
bailout.default = 0.00001;
bailout.hint = "Bailout value; smaller values will cause more iterations to be done for each point.";
relax.caption = "Relaxation";
relax.default = (1,0);
relax.hint = "This can be used to slow down the convergence of the formula.";
}
}
dmj-fBmMandel {
//
// This is the basic Mandelbrot type, but with a
// bit of fBm noise added at each iteration. This
// tends to distort the fractal beyond all recognition
// after just a few iterations, which may or may not
// be what you're looking for.
//
// You can also use the "Coloring Only" option to
// restrict the fBm distortion to the value passed
// to the coloring algorithm; the distortion will be
// removed before the next iteration is calculated.
//
parameter complex start;
complex oz;
complex c;
parameter complex distcenter;
parameter bool centermove;
complex r;
parameter real Parm_angle;
complex r2;
parameter real anglestep;
complex r3;
parameter real distangle;
real fiter;
parameter real noisestart;
bool noise;
parameter real noiseskip;
parameter real noiseiter;
parameter bool coloronly;
parameter complex power;
complex p;
parameter real scale;
parameter complex offset;
real sum;
real freq;
complex v;
int i;
parameter real octaves;
real bx0;
real by0;
real bx1;
real by1;
real rx0;
real ry0;
real rx1;
real ry1;
real b00;
parameter real npower;
real b10;
real b01;
real b11;
real g_b00_0;
real g_b10_0;
real g_b01_0;
real g_b11_0;
real g_b00_1;
real g_b10_1;
real g_b01_1;
real g_b11_1;
real d;
real u1;
real v1;
real u2;
real v2;
real sx;
real sy;
real a;
real b;
parameter real step;
parameter int style;
parameter real distortion;
parameter real bailout;
void init(void)
{
z = start;
oz = z;
c = distcenter;
if ((centermove))
{
c = center;
}
r = (0,1) ^ (Parm_angle / 90.0);
r2 = (0,1) ^ (anglestep / 90.0);
r3 = (0,1) ^ (distangle / 90.0);
fiter = noisestart;
noise = false;
}
void loop(void)
{
if ((noiseskip != 0))
{// we are skipping some iterations
fiter = fiter - 1;// one less to go before we add noise
while ((fiter < 0.0))
{// iterations all used up
if ((noise))
{// we are currently adding noise
noise = false;// so stop
fiter = fiter + noiseskip;// skip this many iterations
}
else
{
// we aren't currently adding noise
noise = true;// so start
fiter = fiter + noiseiter;// do this many iterations
}
}
}
if ((coloronly))
{// only using fBm on coloring
z = oz;// restore z from un-fBm'ed copy
}
z = z^power + pixel;// do Mandelbrot iteration
if ((coloronly))
{// only using fBm on coloring
oz = z;
}
if ((noiseskip == 0.0 || noise))
{// adding noise this iteration
p = z * scale * r + offset;
sum = 0.0;
freq = 1.0;
v = (0,0);
i = octaves;
while ((i > 0))
{
// determine integer coordinate for corners of square
// surrounding p
bx0 = floor(real(p)) % 256;
by0 = floor(imag(p)) % 256;
if ((bx0 < 0))
{
bx0 = bx0 + 256;
}
if ((by0 < 0))
{
by0 = by0 + 256;
}
bx1 = (bx0 + 1) % 256;
by1 = (by0 + 1) % 256;
rx0 = real(p) - floor(real(p));
ry0 = imag(p) - floor(imag(p));
rx1 = rx0 - 1;
ry1 = ry0 - 1;
// create a "random" index for each corner
// (this is where Intel's version differs from Perlin's;
// I used Intel's version because it doesn't require a
// pre-computed random table, which is difficult to manage
// in UF.)
b00 = (bx0^npower % 65536 + by0)^npower % 65536;
b10 = (bx1^npower % 65536 + by0)^npower % 65536;
b01 = (bx0^npower % 65536 + by1)^npower % 65536;
b11 = (bx1^npower % 65536 + by1)^npower % 65536;
// produce a "random" vector for each corner
g_b00_0 = (b00)^npower*0.25 % 512 - 256;
g_b10_0 = (b10)^npower*0.25 % 512 - 256;
g_b01_0 = (b01)^npower*0.25 % 512 - 256;
g_b11_0 = (b11)^npower*0.25 % 512 - 256;
g_b00_1 = (b00+1)^npower*0.25 % 512 - 256;
g_b10_1 = (b10+1)^npower*0.25 % 512 - 256;
g_b01_1 = (b01+1)^npower*0.25 % 512 - 256;
g_b11_1 = (b11+1)^npower*0.25 % 512 - 256;
// normalize each vector
d = 0.0;//
d = 1 / sqrt(sqr(g_b00_0) + sqr(g_b00_1));
g_b00_0 = g_b00_0 * d;
g_b00_1 = g_b00_1 * d;
d = 1 / sqrt(sqr(g_b10_0) + sqr(g_b10_1));
g_b10_0 = g_b10_0 * d;
g_b10_1 = g_b10_1 * d;
d = 1 / sqrt(sqr(g_b01_0) + sqr(g_b01_1));
g_b01_0 = g_b01_0 * d;
g_b01_1 = g_b01_1 * d;
d = 1 / sqrt(sqr(g_b11_0) + sqr(g_b11_1));
g_b11_0 = g_b11_0 * d;
g_b11_1 = g_b11_1 * d;
// produce colors for each corner
u1 = rx0 * g_b00_0 + ry0 * g_b00_1;
v1 = rx1 * g_b10_0 + ry0 * g_b10_1;
u2 = rx0 * g_b01_0 + ry1 * g_b01_1;
v2 = rx1 * g_b11_0 + ry1 * g_b11_1;
// interpolate between corners using
// bilinear filtering
sx = sqr(rx0) * (3 - rx0*2);
sy = sqr(ry0) * (3 - ry0*2);
a = u1 + sx*(v1-u1);
b = u2 + sx*(v2-u2);
sum = sum + (a + sy*(b-a))*freq;
freq = freq * step;
p = p * r2 / step;
i = i - 1;
}
if ((style == 0))
{// radial distortion
v = (z-c)/cabs(z-c) * r3;// use vector based on angle to distortion center
}
else if ((style == 1))
{// linear distortion
v = r3;// just use rotation vector
}
z = z + v * sum*0.5*distortion;
}
if ((coloronly == false))
{// not just using fBm on coloring
oz = z;// value for bailout is fBm'ed z
}
}
bool bailout(void)
{
return(|oz| < bailout);
}
void description(void)
{
this.title = "Mandelbrot + fBm";
this.helpfile = "dmj-pub\dmj-pub-uf-mjf.htm";
this.center = (-0.5,0);
this.magn = 1.0;
start.caption = "Start Value";
start.default = (0,0);
start.hint = "Starting value for each point. You can use this to 'perturb' the fractal.";
power.caption = "Exponent";
power.default = (2,0);
power.hint = "Overall exponent for the equation. (2,0) gives the classic Mandelbrot type.";
bailout.caption = "Bailout";
bailout.default = 1.0e20;
bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Mandelbrot set anymore.";
distortion.caption = "Distortion Strength";
distortion.default = 1.0;
distortion.hint = "This is the amount the noise distorts the image.";
style.caption = "Distortion Style";
style.default = 0;
style.enum = "radial\nlinear";
style.hint = "This selects whether the distortion will be focused around a single point, or directed along a line.";
distangle.caption = "Distortion Angle";
distangle.default = 0.0;
distangle.hint = "This is the angle to rotate the distortion.";
distcenter.caption = "Distortion Center";
distcenter.default = (0,0);
distcenter.hint = "Sets the center of distortion. If Use Screen Center is set, this item is ignored.";
centermove.caption = "Use Screen Center";
centermove.default = FALSE;
centermove.hint = "If set, distortion will be around the center of the window, regardless of the Distortion Center setting.";
offset.caption = "Noise Offset";
offset.default = (0,0);
offset.hint = "This is the offset of the pattern. You can use this to shift the pattern around on the complex plane.";
scale.caption = "Noise Scale";
scale.default = 1.0;
scale.hint = "This is the overall scale of the noise.";
Parm_angle.caption = "Noise Rotation";
Parm_angle.default = 0.0;
Parm_angle.hint = "This is the angle, in degrees, of the noise.";
step.caption = "Noise Scale Step";
step.default = 0.5;
step.hint = "This is the step in scale between noise iterations.";
anglestep.caption = "Noise Rotation Step";
anglestep.default = 37.0;
anglestep.hint = "This is the angle, in degrees, to rotate between noise iterations.";
octaves.caption = "Noise Octaves";
octaves.default = 7;
octaves.min = 1;
octaves.hint = "This is the number of iterations of the noise formula.";
npower.caption = "Noise Exponent";
npower.default = 2.0;
npower.hint = "This is the exponent used to scramble numbers.";
noisestart.caption = "Start Iteration";
noisestart.default = 0.0;
noisestart.hint = "This is the iteration at which to start adding noise.";
noiseiter.caption = "Noise Iterations";
noiseiter.default = 10000.0;
noiseiter.hint = "This is the number of iterations to add noise to.";
noiseskip.caption = "Skip Iterations";
noiseskip.default = 0.0;
noiseskip.hint = "This is the number of iterations to skip adding noise before starting again.";
coloronly.caption = "Coloring Only";
coloronly.default = false;
coloronly.hint = "If set, noise will only apply to pixel values passed to the coloring algorithm; it will not be included in the fractal calculation between iterations.";
}
}
dmj-fBmJulia {
//
// This is the basic Julia type, but with a
// bit of fBm noise added at each iteration. This
// tends to distort the fractal beyond all recognition
// after just a few iterations, which may or may not
// be what you're looking for.
//
// You can also use the "Coloring Only" option to
// restrict the fBm distortion to the value passed
// to the coloring algorithm; the distortion will be
// removed before the next iteration is calculated.
//
complex oz;
complex c;
parameter complex distcenter;
parameter bool centermove;
complex r;
parameter real Parm_angle;
complex r2;
parameter real anglestep;
complex r3;
parameter real distangle;
real fiter;
parameter real noisestart;
bool noise;
parameter real noiseskip;
parameter real noiseiter;
parameter bool coloronly;
parameter complex power;
parameter complex seed;
complex p;
parameter real scale;
parameter complex offset;
real sum;
real freq;
complex v;
int i;
parameter real octaves;
real bx0;
real by0;
real bx1;
real by1;
real rx0;
real ry0;
real rx1;
real ry1;
real b00;
parameter real npower;
real b10;
real b01;
real b11;
real g_b00_0;
real g_b10_0;
real g_b01_0;
real g_b11_0;
real g_b00_1;
real g_b10_1;
real g_b01_1;
real g_b11_1;
real d;
real u1;
real v1;
real u2;
real v2;
real sx;
real sy;
real a;
real b;
parameter real step;
parameter int style;
parameter real distortion;
parameter real bailout;
void init(void)
{
z = pixel;
oz = z;
c = distcenter;
if ((centermove))
{
c = center;
}
r = (0,1) ^ (Parm_angle / 90.0);
r2 = (0,1) ^ (anglestep / 90.0);
r3 = (0,1) ^ (distangle / 90.0);
fiter = noisestart;
noise = false;
}
void loop(void)
{
if ((noiseskip != 0))
{// we are skipping some iterations
fiter = fiter - 1;// one less to go before we add noise
while ((fiter < 0.0))
{// iterations all used up
if ((noise))
{// we are currently adding noise
noise = false;// so stop
fiter = fiter + noiseskip;// skip this many iterations
}
else
{
// we aren't currently adding noise
noise = true;// so start
fiter = fiter + noiseiter;// do this many iterations
}
}
}
if ((coloronly))
{// only using fBm on coloring
z = oz;// restore z from un-fBm'ed copy
}
z = z^power + seed;// do Julia iteration
if ((coloronly))
{// only using fBm on coloring
oz = z;
}
if ((noiseskip == 0.0 || noise))
{// adding noise this iteration
p = z * scale * r + offset;
sum = 0.0;
freq = 1.0;
v = (0,0);
i = octaves;
while ((i > 0))
{
// determine integer coordinate for corners of square
// surrounding p
bx0 = floor(real(p)) % 256;
by0 = floor(imag(p)) % 256;
if ((bx0 < 0))
{
bx0 = bx0 + 256;
}
if ((by0 < 0))
{
by0 = by0 + 256;
}
bx1 = (bx0 + 1) % 256;
by1 = (by0 + 1) % 256;
rx0 = real(p) - floor(real(p));
ry0 = imag(p) - floor(imag(p));
rx1 = rx0 - 1;
ry1 = ry0 - 1;
// create a "random" index for each corner
// (this is where Intel's version differs from Perlin's;
// I used Intel's version because it doesn't require a
// pre-computed random table, which is difficult to manage
// in UF.)
b00 = (bx0^npower % 65536 + by0)^npower % 65536;
b10 = (bx1^npower % 65536 + by0)^npower % 65536;
b01 = (bx0^npower % 65536 + by1)^npower % 65536;
b11 = (bx1^npower % 65536 + by1)^npower % 65536;
// produce a "random" vector for each corner
g_b00_0 = (b00)^npower*0.25 % 512 - 256;
g_b10_0 = (b10)^npower*0.25 % 512 - 256;
g_b01_0 = (b01)^npower*0.25 % 512 - 256;
g_b11_0 = (b11)^npower*0.25 % 512 - 256;
g_b00_1 = (b00+1)^npower*0.25 % 512 - 256;
g_b10_1 = (b10+1)^npower*0.25 % 512 - 256;
g_b01_1 = (b01+1)^npower*0.25 % 512 - 256;
g_b11_1 = (b11+1)^npower*0.25 % 512 - 256;
// normalize each vector
d = 0.0;//
d = 1 / sqrt(sqr(g_b00_0) + sqr(g_b00_1));
g_b00_0 = g_b00_0 * d;
g_b00_1 = g_b00_1 * d;
d = 1 / sqrt(sqr(g_b10_0) + sqr(g_b10_1));
g_b10_0 = g_b10_0 * d;
g_b10_1 = g_b10_1 * d;
d = 1 / sqrt(sqr(g_b01_0) + sqr(g_b01_1));
g_b01_0 = g_b01_0 * d;
g_b01_1 = g_b01_1 * d;
d = 1 / sqrt(sqr(g_b11_0) + sqr(g_b11_1));
g_b11_0 = g_b11_0 * d;
g_b11_1 = g_b11_1 * d;
// produce colors for each corner
u1 = rx0 * g_b00_0 + ry0 * g_b00_1;
v1 = rx1 * g_b10_0 + ry0 * g_b10_1;
u2 = rx0 * g_b01_0 + ry1 * g_b01_1;
v2 = rx1 * g_b11_0 + ry1 * g_b11_1;
// interpolate between corners using
// bilinear filtering
sx = sqr(rx0) * (3 - rx0*2);
sy = sqr(ry0) * (3 - ry0*2);
a = u1 + sx*(v1-u1);
b = u2 + sx*(v2-u2);
sum = sum + (a + sy*(b-a))*freq;
freq = freq * step;
p = p * r2 / step;
i = i - 1;
}
if ((style == 0))
{// radial distortion
v = (z-c)/cabs(z-c) * r3;// use vector based on angle to distortion center
}
else if ((style == 1))
{// linear distortion
v = r3;// just use rotation vector
}
z = z + v * sum*0.5*distortion;
}
if ((coloronly == false))
{// not just using fBm on coloring
oz = z;// value for bailout is fBm'ed z
}
}
bool bailout(void)
{
return(|oz| < bailout);
}
void description(void)
{
this.title = "Julia + fBm";
this.helpfile = "dmj-pub\dmj-pub-uf-mjf.htm";
this.center = (-0.5,0);
this.magn = 1.0;
seed.caption = "Julia Seed";
seed.default = (0,0);
seed.hint = "This is the Julia seed, a constant parameter which defines the shape of the fractal.";
power.caption = "Exponent";
power.default = (2,0);
power.hint = "Overall exponent for the equation. (2,0) gives the classic Julia type.";
bailout.caption = "Bailout";
bailout.default = 1.0e20;
bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Julia set anymore.";
distortion.caption = "Distortion Strength";
distortion.default = 1.0;
distortion.hint = "This is the amount the noise distorts the image.";
style.caption = "Distortion Style";
style.default = 0;
style.enum = "radial\nlinear";
style.hint = "This selects whether the distortion will be focused around a single point, or directed along a line.";
distangle.caption = "Distortion Angle";
distangle.default = 0.0;
distangle.hint = "This is the angle to rotate the distortion.";
distcenter.caption = "Distortion Center";
distcenter.default = (0,0);
distcenter.hint = "Sets the center of distortion. If Use Screen Center is set, this item is ignored.";
centermove.caption = "Use Screen Center";
centermove.default = FALSE;
centermove.hint = "If set, distortion will be around the center of the window, regardless of the Distortion Center setting.";
offset.caption = "Noise Offset";
offset.default = (0,0);
offset.hint = "This is the offset of the pattern. You can use this to shift the pattern around on the complex plane.";
scale.caption = "Noise Scale";
scale.default = 1.0;
scale.hint = "This is the overall scale of the noise.";
Parm_angle.caption = "Noise Rotation";
Parm_angle.default = 0.0;
Parm_angle.hint = "This is the angle, in degrees, of the noise.";
step.caption = "Noise Scale Step";
step.default = 0.5;
step.hint = "This is the step in scale between noise iterations.";
anglestep.caption = "Noise Rotation Step";
anglestep.default = 37.0;
anglestep.hint = "This is the angle, in degrees, to rotate between noise iterations.";
octaves.caption = "Noise Octaves";
octaves.default = 7;
octaves.min = 1;
octaves.hint = "This is the number of iterations of the noise formula.";
npower.caption = "Noise Exponent";
npower.default = 2.0;
npower.hint = "This is the exponent used to scramble numbers.";
noisestart.caption = "Start Iteration";
noisestart.default = 0.0;
noisestart.hint = "This is the iteration at which to start adding noise.";
noiseiter.caption = "Noise Iterations";
noiseiter.default = 10000.0;
noiseiter.hint = "This is the number of iterations to add noise to.";
noiseskip.caption = "Skip Iterations";
noiseskip.default = 0.0;
noiseskip.hint = "This is the number of iterations to skip adding noise before starting again.";
coloronly.caption = "Coloring Only";
coloronly.default = false;
coloronly.hint = "If set, noise will only apply to pixel values passed to the coloring algorithm; it will not be included in the fractal calculation between iterations.";
}
}
dmj-fBmNovaMandel {
//
// This is the basic Nova (Mandelbrot) type, but with a
// bit of fBm noise added at each iteration. This
// tends to distort the fractal beyond all recognition
// after just a few iterations, which may or may not
// be what you're looking for.
//
// You can also use the "Coloring Only" option to
// restrict the fBm distortion to the value passed
// to the coloring algorithm; the distortion will be
// removed before the next iteration is calculated.
//
complex zsquared;
complex zcubed;
complex zold;
parameter complex start;
complex oz;
complex c;
parameter complex distcenter;
parameter bool centermove;
complex r;
parameter real Parm_angle;
complex r2;
parameter real anglestep;
complex r3;
parameter real distangle;
real fiter;
parameter real noisestart;
bool noise;
parameter real noiseskip;
parameter real noiseiter;
parameter bool coloronly;
parameter complex power;
parameter complex relax;
complex p;
parameter real scale;
real sum;
real freq;
complex v;
int i;
parameter real octaves;
real bx0;
real by0;
real bx1;
real by1;
real rx0;
real ry0;
real rx1;
real ry1;
real b00;
parameter real npower;
real b10;
real b01;
real b11;
real g_b00_0;
real g_b10_0;
real g_b01_0;
real g_b11_0;
real g_b00_1;
real g_b10_1;
real g_b01_1;
real g_b11_1;
real d;
real u1;
real v1;
real u2;
real v2;
real sx;
real sy;
real a;
real b;
parameter real step;
parameter int style;
parameter real distortion;
parameter real bailout;
void init(void)
{
zsquared = (0,0);
zcubed = (0,0);
zold = (0,0);
z = start;
oz = z;
c = distcenter;
if ((centermove))
{
c = center;
}
r = (0,1) ^ (Parm_angle / 90.0);
r2 = (0,1) ^ (anglestep / 90.0);
r3 = (0,1) ^ (distangle / 90.0);
fiter = noisestart;
noise = false;
}
void loop(void)
{
if ((noiseskip != 0))
{// we are skipping some iterations
fiter = fiter - 1;// one less to go before we add noise
while ((fiter < 0.0))
{// iterations all used up
if ((noise))
{// we are currently adding noise
noise = false;// so stop
fiter = fiter + noiseskip;// skip this many iterations
}
else
{
// we aren't currently adding noise
noise = true;// so start
fiter = fiter + noiseiter;// do this many iterations
}
}
}
if ((coloronly))
{// only using fBm on coloring
z = oz;// restore z from un-fBm'ed copy
}
if ((power == (3,0)))
{// special optimized routine for power 3
zsquared = sqr(z);
zcubed = zsquared * z;
zold = z;
z = z - relax * (zcubed-1) / (3*zsquared) + pixel;
}
else
{
zold = z;
z = z - relax * (z^power-1) / (power * z^(power-1)) + pixel;
}
if ((coloronly))
{// only using fBm on coloring
oz = z;
}
if ((noiseskip == 0.0 || noise))
{// adding noise this iteration
p = z * scale * r;//+ @offset
sum = 0.0;
freq = 1.0;
v = (0,0);
i = octaves;
while ((i > 0))
{
// determine integer coordinate for corners of square
// surrounding p
bx0 = floor(real(p)) % 256;
by0 = floor(imag(p)) % 256;
if ((bx0 < 0))
{
bx0 = bx0 + 256;
}
if ((by0 < 0))
{
by0 = by0 + 256;
}
bx1 = (bx0 + 1) % 256;
by1 = (by0 + 1) % 256;
rx0 = real(p) - floor(real(p));
ry0 = imag(p) - floor(imag(p));
rx1 = rx0 - 1;
ry1 = ry0 - 1;
// create a "random" index for each corner
// (this is where Intel's version differs from Perlin's;
// I used Intel's version because it doesn't require a
// pre-computed random table, which is difficult to manage
// in UF.)
b00 = (bx0^npower % 65536 + by0)^npower % 65536;
b10 = (bx1^npower % 65536 + by0)^npower % 65536;
b01 = (bx0^npower % 65536 + by1)^npower % 65536;
b11 = (bx1^npower % 65536 + by1)^npower % 65536;
// produce a "random" vector for each corner
g_b00_0 = (b00)^npower*0.25 % 512 - 256;
g_b10_0 = (b10)^npower*0.25 % 512 - 256;
g_b01_0 = (b01)^npower*0.25 % 512 - 256;
g_b11_0 = (b11)^npower*0.25 % 512 - 256;
g_b00_1 = (b00+1)^npower*0.25 % 512 - 256;
g_b10_1 = (b10+1)^npower*0.25 % 512 - 256;
g_b01_1 = (b01+1)^npower*0.25 % 512 - 256;
g_b11_1 = (b11+1)^npower*0.25 % 512 - 256;
// normalize each vector
d = 0.0;//
d = 1 / sqrt(sqr(g_b00_0) + sqr(g_b00_1));
g_b00_0 = g_b00_0 * d;
g_b00_1 = g_b00_1 * d;
d = 1 / sqrt(sqr(g_b10_0) + sqr(g_b10_1));
g_b10_0 = g_b10_0 * d;
g_b10_1 = g_b10_1 * d;
d = 1 / sqrt(sqr(g_b01_0) + sqr(g_b01_1));
g_b01_0 = g_b01_0 * d;
g_b01_1 = g_b01_1 * d;
d = 1 / sqrt(sqr(g_b11_0) + sqr(g_b11_1));
g_b11_0 = g_b11_0 * d;
g_b11_1 = g_b11_1 * d;
// produce colors for each corner
u1 = rx0 * g_b00_0 + ry0 * g_b00_1;
v1 = rx1 * g_b10_0 + ry0 * g_b10_1;
u2 = rx0 * g_b01_0 + ry1 * g_b01_1;
v2 = rx1 * g_b11_0 + ry1 * g_b11_1;
// interpolate between corners using
// bilinear filtering
sx = sqr(rx0) * (3 - rx0*2);
sy = sqr(ry0) * (3 - ry0*2);
a = u1 + sx*(v1-u1);
b = u2 + sx*(v2-u2);
sum = sum + (a + sy*(b-a))*freq;
freq = freq * step;
p = p * r2 / step;
i = i - 1;
}
if ((style == 0))
{// radial distortion
v = (z-c)/cabs(z-c) * r3;// use vector based on angle to distortion center
}
else if ((style == 1))
{// linear distortion
v = r3;// just use rotation vector
}
z = z + v * sum*0.5*distortion;
}
if ((coloronly == false))
{// not just using fBm on coloring
oz = z;// value for bailout is fBm'ed z
}
}
bool bailout(void)
{
return(|oz - zold| > bailout);
}
void description(void)
{
this.title = "Nova (Mandelbrot) + fBm";
this.helpfile = "dmj-pub\dmj-pub-uf-nf.htm";
this.maxiter = 1000;
this.periodicity = 0;
this.center = (-0.5,0);
this.magn = 1.5;
start.caption = "Start Value";
start.default = (1,0);
start.hint = "Starting value for each point. You can use this to 'perturb' the fractal.";
power.caption = "Exponent";
power.default = (3,0);
power.hint = "Overall exponent for the equation. (3,0) gives the classic NovaM type.";
bailout.caption = "Bailout";
bailout.default = 0.00001;
bailout.hint = "Bailout value; smaller values will cause more iterations to be done for each point.";
relax.caption = "Relaxation";
relax.default = (1,0);
relax.hint = "This can be used to slow down the convergence of the formula.";
distortion.caption = "Distortion Strength";
distortion.default = 1.0;
distortion.hint = "This is the amount the noise distorts the image.";
style.caption = "Distortion Style";
style.default = 0;
style.enum = "radial\nlinear";
style.hint = "This selects whether the distortion will be focused around a single point, or directed along a line.";
distangle.caption = "Distortion Angle";
distangle.default = 0.0;
distangle.hint = "This is the angle to rotate the distortion.";
distcenter.caption = "Distortion Center";
distcenter.default = (0,0);
distcenter.hint = "Sets the center of distortion. If Use Screen Center is set, this item is ignored.";
centermove.caption = "Use Screen Center";
centermove.default = FALSE;
centermove.hint = "If set, distortion will be around the center of the window, regardless of the Distortion Center setting.";
offset.caption = "Noise Offset";
offset.default = (0,0);
offset.hint = "This is the offset of the pattern. You can use this to shift the pattern around on the complex plane.";
scale.caption = "Noise Scale";
scale.default = 1.0;
scale.hint = "This is the overall scale of the noise.";
Parm_angle.caption = "Noise Rotation";
Parm_angle.default = 0.0;
Parm_angle.hint = "This is the angle, in degrees, of the noise.";
step.caption = "Noise Scale Step";
step.default = 0.5;
step.hint = "This is the step in scale between noise iterations.";
anglestep.caption = "Noise Rotation Step";
anglestep.default = 37.0;
anglestep.hint = "This is the angle, in degrees, to rotate between noise iterations.";
octaves.caption = "Noise Octaves";
octaves.default = 7;
octaves.min = 1;
octaves.hint = "This is the number of iterations of the noise formula.";
npower.caption = "Noise Exponent";
npower.default = 2.0;
npower.hint = "This is the exponent used to scramble numbers.";
noisestart.caption = "Start Iteration";
noisestart.default = 0.0;
noisestart.hint = "This is the iteration at which to start adding noise.";
noiseiter.caption = "Noise Iterations";
noiseiter.default = 10000.0;
noiseiter.hint = "This is the number of iterations to add noise to.";
noiseskip.caption = "Skip Iterations";
noiseskip.default = 0.0;
noiseskip.hint = "This is the number of iterations to skip adding noise before starting again.";
coloronly.caption = "Coloring Only";
coloronly.default = false;
coloronly.hint = "If set, noise will only apply to pixel values passed to the coloring algorithm; it will not be included in the fractal calculation between iterations.";
}
}
dmj-fBmNovaJulia {
//
// This is the basic Nova (Mandelbrot) type, but with a
// bit of fBm noise added at each iteration. This
// tends to distort the fractal beyond all recognition
// after just a few iterations, which may or may not
// be what you're looking for.
//
// You can also use the "Coloring Only" option to
// restrict the fBm distortion to the value passed
// to the coloring algorithm; the distortion will be
// removed before the next iteration is calculated.
//
complex zsquared;
complex zcubed;
complex zold;
complex oz;
complex c;
parameter complex distcenter;
parameter bool centermove;
complex r;
parameter real Parm_angle;
complex r2;
parameter real anglestep;
complex r3;
parameter real distangle;
real fiter;
parameter real noisestart;
bool noise;
parameter real noiseskip;
parameter real noiseiter;
parameter bool coloronly;
parameter complex power;
parameter complex relax;
parameter complex seed;
complex p;
parameter real scale;
parameter complex offset;
real sum;
real freq;
complex v;
int i;
parameter real octaves;
real bx0;
real by0;
real bx1;
real by1;
real rx0;
real ry0;
real rx1;
real ry1;
real b00;
parameter real npower;
real b10;
real b01;
real b11;
real g_b00_0;
real g_b10_0;
real g_b01_0;
real g_b11_0;
real g_b00_1;
real g_b10_1;
real g_b01_1;
real g_b11_1;
real d;
real u1;
real v1;
real u2;
real v2;
real sx;
real sy;
real a;
real b;
parameter real step;
parameter int style;
parameter real distortion;
parameter real bailout;
void init(void)
{
zsquared = (0,0);
zcubed = (0,0);
zold = (0,0);
z = pixel;
oz = z;
c = distcenter;
if ((centermove))
{
c = center;
}
r = (0,1) ^ (Parm_angle / 90.0);
r2 = (0,1) ^ (anglestep / 90.0);
r3 = (0,1) ^ (distangle / 90.0);
fiter = noisestart;
noise = false;
}
void loop(void)
{
if ((noiseskip != 0))
{// we are skipping some iterations
fiter = fiter - 1;// one less to go before we add noise
while ((fiter < 0.0))
{// iterations all used up
if ((noise))
{// we are currently adding noise
noise = false;// so stop
fiter = fiter + noiseskip;// skip this many iterations
}
else
{
// we aren't currently adding noise
noise = true;// so start
fiter = fiter + noiseiter;// do this many iterations
}
}
}
if ((coloronly))
{// only using fBm on coloring
z = oz;// restore z from un-fBm'ed copy
}
if ((power == (3,0)))
{// special optimized routine for power 3
zsquared = sqr(z);
zcubed = zsquared * z;
zold = z;
z = z - relax * (zcubed-1) / (3*zsquared) + seed;
}
else
{
zold = z;
z = z - relax * (z^power-1) / (power * z^(power-1)) + seed;
}
if ((coloronly))
{// only using fBm on coloring
oz = z;
}
if ((noiseskip == 0.0 || noise))
{// adding noise this iteration
p = z * scale * r + offset;
sum = 0.0;
freq = 1.0;
v = (0,0);
i = octaves;
while ((i > 0))
{
// determine integer coordinate for corners of square
// surrounding p
bx0 = floor(real(p)) % 256;
by0 = floor(imag(p)) % 256;
if ((bx0 < 0))
{
bx0 = bx0 + 256;
}
if ((by0 < 0))
{
by0 = by0 + 256;
}
bx1 = (bx0 + 1) % 256;
by1 = (by0 + 1) % 256;
rx0 = real(p) - floor(real(p));
ry0 = imag(p) - floor(imag(p));
rx1 = rx0 - 1;
ry1 = ry0 - 1;
// create a "random" index for each corner
// (this is where Intel's version differs from Perlin's;
// I used Intel's version because it doesn't require a
// pre-computed random table, which is difficult to manage
// in UF.)
b00 = (bx0^npower % 65536 + by0)^npower % 65536;
b10 = (bx1^npower % 65536 + by0)^npower % 65536;
b01 = (bx0^npower % 65536 + by1)^npower % 65536;
b11 = (bx1^npower % 65536 + by1)^npower % 65536;
// produce a "random" vector for each corner
g_b00_0 = (b00)^npower*0.25 % 512 - 256;
g_b10_0 = (b10)^npower*0.25 % 512 - 256;
g_b01_0 = (b01)^npower*0.25 % 512 - 256;
g_b11_0 = (b11)^npower*0.25 % 512 - 256;
g_b00_1 = (b00+1)^npower*0.25 % 512 - 256;
g_b10_1 = (b10+1)^npower*0.25 % 512 - 256;
g_b01_1 = (b01+1)^npower*0.25 % 512 - 256;
g_b11_1 = (b11+1)^npower*0.25 % 512 - 256;
// normalize each vector
d = 0.0;//
d = 1 / sqrt(sqr(g_b00_0) + sqr(g_b00_1));
g_b00_0 = g_b00_0 * d;
g_b00_1 = g_b00_1 * d;
d = 1 / sqrt(sqr(g_b10_0) + sqr(g_b10_1));
g_b10_0 = g_b10_0 * d;
g_b10_1 = g_b10_1 * d;
d = 1 / sqrt(sqr(g_b01_0) + sqr(g_b01_1));
g_b01_0 = g_b01_0 * d;
g_b01_1 = g_b01_1 * d;
d = 1 / sqrt(sqr(g_b11_0) + sqr(g_b11_1));
g_b11_0 = g_b11_0 * d;
g_b11_1 = g_b11_1 * d;
// produce colors for each corner
u1 = rx0 * g_b00_0 + ry0 * g_b00_1;
v1 = rx1 * g_b10_0 + ry0 * g_b10_1;
u2 = rx0 * g_b01_0 + ry1 * g_b01_1;
v2 = rx1 * g_b11_0 + ry1 * g_b11_1;
// interpolate between corners using
// bilinear filtering
sx = sqr(rx0) * (3 - rx0*2);
sy = sqr(ry0) * (3 - ry0*2);
a = u1 + sx*(v1-u1);
b = u2 + sx*(v2-u2);
sum = sum + (a + sy*(b-a))*freq;
freq = freq * step;
p = p * r2 / step;
i = i - 1;
}
if ((style == 0))
{// radial distortion
v = (z-c)/cabs(z-c) * r3;// use vector based on angle to distortion center
}
else if ((style == 1))
{// linear distortion
v = r3;// just use rotation vector
}
z = z + v * sum*0.5*distortion;
}
if ((coloronly == false))
{// not just using fBm on coloring
oz = z;// value for bailout is fBm'ed z
}
}
bool bailout(void)
{
return(|oz - zold| > bailout);
}
void description(void)
{
this.title = "Nova (Julia) + fBm";
this.helpfile = "dmj-pub\dmj-pub-uf-nf.htm";
this.maxiter = 1000;
this.periodicity = 0;
this.center = (0,0);
this.magn = 1.5;
seed.caption = "Julia Seed";
seed.default = (0,0);
seed.hint = "This is the Julia seed, a constant parameter which defines the shape of the fractal.";
power.caption = "Exponent";
power.default = (3,0);
power.hint = "Overall exponent for the equation. (3,0) gives the classic Nova type.";
bailout.caption = "Bailout";
bailout.default = 0.00001;
bailout.hint = "Bailout value; smaller values will cause more iterations to be done for each point.";
relax.caption = "Relaxation";
relax.default = (1,0);
relax.hint = "This can be used to slow down the convergence of the formula.";
distortion.caption = "Distortion Strength";
distortion.default = 1.0;
distortion.hint = "This is the amount the noise distorts the image.";
style.caption = "Distortion Style";
style.default = 0;
style.enum = "radial\nlinear";
style.hint = "This selects whether the distortion will be focused around a single point, or directed along a line.";
distangle.caption = "Distortion Angle";
distangle.default = 0.0;
distangle.hint = "This is the angle to rotate the distortion.";
distcenter.caption = "Distortion Center";
distcenter.default = (0,0);
distcenter.hint = "Sets the center of distortion. If Use Screen Center is set, this item is ignored.";
centermove.caption = "Use Screen Center";
centermove.default = FALSE;
centermove.hint = "If set, distortion will be around the center of the window, regardless of the Distortion Center setting.";
offset.caption = "Noise Offset";
offset.default = (0,0);
offset.hint = "This is the offset of the pattern. You can use this to shift the pattern around on the complex plane.";
scale.caption = "Noise Scale";
scale.default = 1.0;
scale.hint = "This is the overall scale of the noise.";
Parm_angle.caption = "Noise Rotation";
Parm_angle.default = 0.0;
Parm_angle.hint = "This is the angle, in degrees, of the noise.";
step.caption = "Noise Scale Step";
step.default = 0.5;
step.hint = "This is the step in scale between noise iterations.";
anglestep.caption = "Noise Rotation Step";
anglestep.default = 37.0;
anglestep.hint = "This is the angle, in degrees, to rotate between noise iterations.";
octaves.caption = "Noise Octaves";
octaves.default = 7;
octaves.min = 1;
octaves.hint = "This is the number of iterations of the noise formula.";
npower.caption = "Noise Exponent";
npower.default = 2.0;
npower.hint = "This is the exponent used to scramble numbers.";
noisestart.caption = "Start Iteration";
noisestart.default = 0.0;
noisestart.hint = "This is the iteration at which to start adding noise.";
noiseiter.caption = "Noise Iterations";
noiseiter.default = 10000.0;
noiseiter.hint = "This is the number of iterations to add noise to.";
noiseskip.caption = "Skip Iterations";
noiseskip.default = 0.0;
noiseskip.hint = "This is the number of iterations to skip adding noise before starting again.";
coloronly.caption = "Coloring Only";
coloronly.default = false;
coloronly.hint = "If set, noise will only apply to pixel values passed to the coloring algorithm; it will not be included in the fractal calculation between iterations.";
start.hint = "Starting value for each point. You can use this to 'perturb' the fractal.";
power.caption = "Exponent";
power.default = (3,0);
power.hint = "Overall exponent for the equation. (3,0) gives the classic NovaM type.";
bailout.caption = "Bailout";
bailout.default = 10000.0;
bailout.hint = "Bailout value; larger values will cause more iterations to be done for each point.";
relax.caption = "Relaxation";
relax.default = (1,0);
relax.hint = "This can be used to slow down the convergence of the formula.";
fudge.caption = "Fudge z Angle";
fudge.default = false;
fudge.hint = "Modifies angle of z based on starting point. Turning this on will make decomposition more consistent between iterations, regardless of the root converged on.";
seed.hint = "This is the Julia seed, a constant parameter which defines the shape of the fractal.";
power.caption = "Exponent";
power.default = (3,0);
power.hint = "Overall exponent for the equation. (3,0) gives the classic NovaM type.";
bailout.caption = "Bailout";
bailout.default = 10000.0;
bailout.hint = "Bailout value; larger values will cause more iterations to be done for each point.";
relax.caption = "Relaxation";
relax.default = (1,0);
relax.hint = "This can be used to slow down the convergence of the formula.";
fudge.caption = "Fudge z Angle";
fudge.default = false;
fudge.hint = "Modifies angle of z based on starting point. Turning this on will make decomposition more consistent between iterations, regardless of the root converged on.";
}
}
dmj-HNovaMandel {
//
// This is the Halley Nova fractal (Mandelbrot
// form), a modified Halley-style fractal. This
// is an adaptation of Paul Derbyshire's Halley
// Nova formulas for FractInt, which are based
// on his "Nova" formulas derived from classical
// Newton's Method fractals.
//
complex nsquaredplusn;
parameter complex power;
complex nsquaredminusn;
complex zton;
complex zold;
parameter complex start;
parameter complex relax;
parameter real bailout;
void init(void)
{
nsquaredplusn = sqr(power) + power;
nsquaredminusn = sqr(power) - power;
zton = (0,0);
zold = (0,0);
z = start;
}
void loop(void)
{
zold = z;
zton = z^power;
z = z - (2*power*z * (zton-1)) * relax / (nsquaredplusn*zton + nsquaredminusn) + pixel;
}
bool bailout(void)
{
return(|z - zold| > bailout);
}
void description(void)
{
this.title = "HalleyNova (Mandelbrot)";
this.helpfile = "dmj-pub\dmj-pub-uf-hn.htm";
this.maxiter = 1000;
this.periodicity = 0;
this.center = (-0.5,0);
this.magn = 1.0;
start.caption = "Start Value";
start.default = (1,0);
start.hint = "Starting value for each point. You can use this to 'perturb' the fractal.";
power.caption = "Exponent";
power.default = (3,0);
power.hint = "Overall exponent for the equation. (3,0) gives the classic HalleyNovaM type.";
bailout.caption = "Bailout";
bailout.default = 0.00001;
bailout.hint = "Bailout value; smaller values will cause more iterations to be done for each point.";
relax.caption = "Relaxation";
relax.default = (1,0);
relax.hint = "This can be used to slow down the convergence of the formula.";
}
}
dmj-HNovaJulia {
//
// This is the Halley Nova fractal (Julia form),
// a modified Halley-style fractal. This is an
// adaptation of Paul Derbyshire's Halley Nova
// formulas for FractInt, which are based on his
// "Nova" formulas derived from classical
// Newton's Method fractals.
//
complex nsquaredplusn;
parameter complex power;
complex nsquaredminusn;
complex zton;
complex zold;
parameter complex relax;
parameter complex seed;
parameter real bailout;
void init(void)
{
nsquaredplusn = sqr(power) + power;
nsquaredminusn = sqr(power) - power;
zton = (0,0);
zold = (0,0);
z = pixel;
}
void loop(void)
{
zold = z;
zton = z^power;
z = z - (2*power*z * (zton-1)) * relax /(nsquaredplusn*zton + nsquaredminusn) + seed;
}
bool bailout(void)
{
return(|z - zold| > bailout);
}
void description(void)
{
this.title = "HalleyNova (Julia)";
this.helpfile = "dmj-pub\dmj-pub-uf-hn.htm";
this.maxiter = 1000;
this.periodicity = 0;
this.center = (0,0);
this.magn = 0.5;
seed.caption = "Julia Seed";
seed.default = (0,0);
seed.hint = "This is the Julia seed, a constant parameter which defines the shape of the fractal.";
power.caption = "Exponent";
power.default = (3,0);
power.hint = "Overall exponent for the equation. (3,0) gives the classic HalleyNovaJ type.";
bailout.caption = "Bailout";
bailout.default = 0.00001;
bailout.hint = "Bailout value; smaller values will cause more iterations to be done for each point.";
relax.caption = "Relaxation";
relax.default = (1,0);
relax.hint = "This can be used to slow down the convergence of the formula.";
}
}
dmj-IMandel {
//
// This is a modified Mandelbrot formula which
// returns 1/z in z. This is useful for coloring
// algorithms which expect convergent orbits.
//
parameter complex start;
parameter complex invcenter;
complex z2;
complex z3;
parameter bool invdelta;
parameter complex power;
parameter real bailout;
void init(void)
{
if ((start == (0,0)))
{
z = 1 / (pixel-invcenter);
}
else
{
z = 1 / (start-invcenter);
}
z2 = (0,0);
z3 = (0,0);
}
void loop(void)
{
z = 1/z + invcenter;
if ((invdelta == true))
{
z = z + z2;
z2 = z;
}
z = z^power + pixel;
if ((invdelta == true))
{
z = z - z2;
}
z = 1 / (z-invcenter);
}
bool bailout(void)
{
return(|z| > bailout);
}
void description(void)
{
this.title = "Mandelbrot (Inverted)";
this.helpfile = "dmj-pub\dmj-pub-uf-mji.htm";
this.maxiter = 1000;
this.center = (-0.5,0);
start.caption = "Start Value";
start.default = (0,0);
start.hint = "Starting value for each point. You can use this to 'perturb' the fractal.";
power.caption = "Exponent";
power.default = (2,0);
power.hint = "Overall exponent for the equation. (2,0) gives the classic Mandelbrot type.";
bailout.caption = "Bailout";
bailout.default = 1.0e-9;
bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Mandelbrot set anymore. Note that this is an inverse bailout; larger values make points bail out sooner.";
invcenter.caption = "Inversion Center";
invcenter.default = (0,0);
invcenter.hint = "Center of inversion for calculation.";
invdelta.caption = "Use Change in z";
invdelta.default = FALSE;
invdelta.hint = "If set, z will be the inverted change in orbit values, rather than the inverted orbit value itself.";
}
}
dmj-IJulia {
//
// This is a modified Julia formula which
// returns 1/z in z. This is useful for coloring
// algorithms which expect convergent orbits.
//
parameter complex invcenter;
complex z2;
complex z3;
parameter bool invdelta;
parameter complex power;
parameter complex seed;
parameter real bailout;
void init(void)
{
z = 1 / (pixel-invcenter);
z2 = (0,0);
z3 = (0,0);
}
void loop(void)
{
z = 1/z + invcenter;
if ((invdelta == true))
{
z = z + z2;
z2 = z;
}
z = z^power + seed;
if ((invdelta == true))
{
z = z - z2;
}
z = 1 / (z-invcenter);
}
bool bailout(void)
{
return(|z| > bailout);
}
void description(void)
{
this.title = "Julia (Inverted)";
this.helpfile = "dmj-pub\dmj-pub-uf-mji.htm";
this.maxiter = 1000;
this.center = (0,0);
seed.caption = "Julia Seed";
seed.default = (0,0);
seed.hint = "This is the Julia seed, a constant parameter which defines the shape of the fractal.";
power.caption = "Exponent";
power.default = (2,0);
power.hint = "Overall exponent for the equation. (2,0) gives the classic Julia type.";
bailout.caption = "Bailout";
bailout.default = 1.0e-9;
bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Julia set anymore. Note that this is an inverse bailout; larger values make points bail out sooner.";
invcenter.caption = "Inversion Center";
invcenter.default = (0,0);
invcenter.hint = "Center of inversion for calculation.";
invdelta.caption = "Use Change in z";
invdelta.default = FALSE;
invdelta.hint = "If set, z will be the inverted change in orbit values, rather than the inverted orbit value itself.";
}
}
dmj-Julia2-Start {
//
// This is the starting point for Julia2, the periodic-c
// Julia variant. Because this is derived from the basic
// Julia equation, z^2+c, the dmj-Smooth and dmj-Triangle
// coloring algorithms will work with it. Use UF2's
// Switch feature to select the first Julia point.
//
parameter complex power;
parameter real bailout;
void init(void)
{
z = 0;
}
void loop(void)
{
z = z^power + pixel;
}
bool bailout(void)
{
return(|z| < bailout);
}
void description(void)
{
this.title = "Julia2 Start";
this.helpfile = "dmj-pub\dmj-pub-uf-j2.htm";
this.maxiter = 1000;
this.center = (-0.5,0);
switchseeds.caption = "Switch Seeds";
switchseeds.default = FALSE;
switchseeds.hint = "If this is enabled, the Julia seeds will be swapped. NOTE: the effects will not be visible at this stage.";
pattern.caption = "Seed Pattern";
pattern.default = 21;
pattern.min = 12;
pattern.hint = "Defines the pattern in which the two seeds will be used. NOTE: the effects will not be visible at this stage.";
power.caption = "Exponent";
power.default = (2,0);
power.hint = "Overall exponent for the equation. (2,0) gives the classic Julia type.";
bailout.caption = "Bailout";
bailout.default = 1.0e20;
bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Julia2 set anymore.";
}
}
dmj-Julia2-Step1 {
//
// This is the first step in selecting a Julia2 fractal. From
// here, use the Switch feature again to select the second Julia
// point.
//
int p;
parameter real pattern;
int plength;
int pmul;
int pdigit;
bool t;
parameter bool switchseeds;
parameter complex power;
parameter complex seed1;
parameter real bailout;
void init(void)
{
z = 0;
p = pattern;// Starting pattern
plength = floor(log(p)/log(10));// number of digits in the pattern, - 1
pmul = floor(10^plength);// multiplier to get leftmost digit
pdigit = 0;// used for extracted digit
t = false;
if ((p == 21 && switchseeds))
{// special optimized pattern
t = true;// start with the other seed
}
}
void loop(void)
{
if ((p == 21))
{// special optimized pattern
t = !t;// rotate pattern one step
if ((t))
{// using second seed
z = z^power + pixel;
}
else
{
// using first seed
z = z^power + seed1;
}
}
else
{
pdigit = floor(p / pmul);// rotate pattern one step
p = (p-pdigit*pmul)*10 + pdigit;
if ((switchseeds))
{// seeds should be swapped
pdigit = 3 - pdigit;// use the other seed
}
if ((pdigit == 1))
{// using first seed
z = z^power + seed1;
}
else
{
// using second seed
z = z^power + pixel;
}
}
}
bool bailout(void)
{
return(|z| < bailout);
}
void description(void)
{
this.title = "Julia2 Step 1";
this.helpfile = "dmj-pub\dmj-pub-uf-j2.htm";
this.maxiter = 1000;
this.center = (-0.5,0);
seed1.caption = "Julia Seed 1";
seed1.default = (0,0);
seed1.hint = "This is the first Julia seed, a constant parameter which defines the shape of the fractal.";
switchseeds.caption = "Switch Seeds";
switchseeds.default = FALSE;
switchseeds.hint = "If this is enabled, the Julia seeds will be swapped. This lets you try the alternate 'flavor' Julia2 without manually swapping the parameters.";
pattern.caption = "Seed Pattern";
pattern.default = 21;
pattern.min = 12;
pattern.hint = "Defines the pattern in which the two seeds will be used. Each digit indicates the seed to use, 1 or 2; when all digits have been used, the pattern repeats. The default of 21 gives the original Julia2 behavior.";
power.caption = "Exponent";
power.default = (2,0);
power.hint = "Overall exponent for the equation. (2,0) gives the classic Julia type.";
bailout.caption = "Bailout";
bailout.default = 1.0e20;
bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Julia2 set anymore.";
}
}
dmj-Julia2-Step2 {
//
// This is the final alternating-c Julia2 fractal.
// Once both seeds have been selected, you can use
// the Switch feature again to open up a window
// which will let you select the first Julia seed
// again, leaving the second one unchanged.
//
int p;
parameter real pattern;
int plength;
int pmul;
int pdigit;
bool t;
parameter bool switchseeds;
parameter complex power;
parameter complex seed2;
parameter complex seed1;
parameter real bailout;
void init(void)
{
z = pixel;
p = pattern;// Starting pattern
plength = floor(log(p)/log(10));// number of digits in the pattern, - 1
pmul = floor(10^plength);// multiplier to get leftmost digit
pdigit = 0;// used for extracted digit
t = false;
if ((p == 21 && switchseeds))
{// special optimized pattern
t = true;// start with the other seed
}
}
void loop(void)
{
if ((p == 21))
{// special optimized pattern
t = !t;// rotate pattern one step
if ((t))
{// using second seed
z = z^power + seed2;
}
else
{
// using first seed
z = z^power + seed1;
}
}
else
{
pdigit = floor(p / pmul);// rotate pattern one step
p = (p-pdigit*pmul)*10 + pdigit;
if ((switchseeds))
{// seeds should be swapped
pdigit = 3 - pdigit;// use the other seed
}
if ((pdigit == 1))
{// using first seed
z = z^power + seed1;
}
else
{
// using second seed
z = z^power + seed2;
}
}
}
bool bailout(void)
{
return(|z| < bailout);
}
void description(void)
{
this.title = "Julia2 Step 2";
this.helpfile = "dmj-pub\dmj-pub-uf-j2.htm";
this.maxiter = 1000;
seed1.caption = "Julia Seed 1";
seed1.default = (0,0);
seed1.hint = "This is the first Julia seed, a constant parameter which defines the shape of the fractal.";
seed2.caption = "Julia Seed 2";
seed2.default = (0,0);
seed2.hint = "This is the second Julia seed, a constant parameter which defines the shape of the fractal.";
switchseeds.caption = "Switch Seeds";
switchseeds.default = FALSE;
switchseeds.hint = "If this is enabled, the Julia seeds will be swapped. This lets you try the alternate 'flavor' Julia2 without manually swapping the parameters.";
pattern.caption = "Seed Pattern";
pattern.default = 21;
pattern.min = 12;
pattern.hint = "Defines the pattern in which the two seeds will be used. Each digit indicates the seed to use, 1 or 2; when all digits have been used, the pattern repeats. The default of 21 gives the original Julia2 behavior.";
power.caption = "Exponent";
power.default = (2,0);
power.hint = "Overall exponent for the equation. (2,0) gives the classic Julia type.";
bailout.caption = "Bailout";
bailout.default = 1.0e20;
bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Julia2 set anymore.";
}
}
dmj-Julia2-Step1a {
//
// This is the first step in selecting a Julia2 fractal. From
// here, use the Switch feature again to select the second Julia
// point.
//
int p;
parameter real pattern;
int plength;
int pmul;
int pdigit;
bool t;
parameter bool switchseeds;
parameter complex power;
parameter complex seed2;
parameter real bailout;
void init(void)
{
z = 0;
p = pattern;// Starting pattern
plength = floor(log(p)/log(10));// number of digits in the pattern, - 1
pmul = floor(10^plength);// multiplier to get leftmost digit
pdigit = 0;// used for extracted digit
t = false;
if ((p == 21 && switchseeds))
{// special optimized pattern
t = true;// start with the other seed
}
}
void loop(void)
{
if ((p == 21))
{// special optimized pattern
t = !t;// rotate pattern one step
if ((t))
{// using second seed
z = z^power + seed2;
}
else
{
// using first seed
z = z^power + pixel;
}
}
else
{
pdigit = floor(p / pmul);// rotate pattern one step
p = (p-pdigit*pmul)*10 + pdigit;
if ((switchseeds))
{// seeds should be swapped
pdigit = 3 - pdigit;// use the other seed
}
if ((pdigit == 1))
{// using first seed
z = z^power + pixel;
}
else
{
// using second seed
z = z^power + seed2;
}
}
}
bool bailout(void)
{
return(|z| < bailout);
}
void description(void)
{
this.title = "Julia2 Step 1a";
this.helpfile = "dmj-pub\dmj-pub-uf-j2.htm";
this.maxiter = 1000;
this.center = (-0.5,0);
this.periodicity = 0;
seed2.caption = "Julia Seed 2";
seed2.default = (0,0);
seed2.hint = "This is the second Julia seed, a constant parameter which defines the shape of the fractal.";
switchseeds.caption = "Switch Seeds";
switchseeds.default = FALSE;
switchseeds.hint = "If this is enabled, the Julia seeds will be swapped. This lets you try the alternate 'flavor' Julia2 without manually swapping the parameters.";
pattern.caption = "Seed Pattern";
pattern.default = 21;
pattern.min = 12;
pattern.hint = "Defines the pattern in which the two seeds will be used. Each digit indicates the seed to use, 1 or 2; when all digits have been used, the pattern repeats. The default of 21 gives the original Julia2 behavior.";
power.caption = "Exponent";
power.default = (2,0);
power.hint = "Overall exponent for the equation. (2,0) gives the classic Julia type.";
bailout.caption = "Bailout";
bailout.default = 1.0e20;
bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Julia2 set anymore.";
}
}
dmj-Julia3-Start {
//
// This is the starting point for Julia3, the periodic-c
// Julia variant. Because this is derived from the basic
// Julia equation, z^2+c, the dmj-Smooth and dmj-Triangle
// coloring algorithms will work with it. Use UF2's
// Switch feature to select the first Julia point.
seedorder.hint = "Selects the order in which the Julia seeds are used. This parameter is retained for compatibility purposes; new fractals should use 'Custom' and set the order explicitly.";
pattern.caption = "Seed Pattern";
pattern.default = 123;
pattern.min = 12;
pattern.hint = "Defines the pattern in which the two seeds will be used. Each digit indicates the seed to use, 1, 2, or 3; when all digits have been used, the pattern repeats. The default of 123 gives the original Julia3 behavior.";
power.caption = "Exponent";
power.default = (2,0);
power.hint = "Overall exponent for the equation. (2,0) gives the classic Julia type.";
bailout.caption = "Bailout";
bailout.default = 1.0e20;
bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Julia3 set anymore.";
}
}
dmj-Julia3-Step1 {
//
// This is the first step in selecting a Julia3 fractal. From
// here, use the Switch feature again to select the second Julia
// point.
//
int p;
parameter real pattern;
parameter int seedorder;
int plength;
int pmul;
int pdigit;
parameter complex power;
parameter complex seed1;
parameter real bailout;
void init(void)
{
z = 0;
p = pattern;// Starting pattern
if ((seedorder == 0))
{// Preset pattern
p = 123;
}
else if ((seedorder == 1))
{
p = 231;
}
else if ((seedorder == 2))
{
p = 312;
}
else if ((seedorder == 3))
{
p = 321;
}
else if ((seedorder == 4))
{
p = 213;
}
else if ((seedorder == 5))
{
p = 132;
}
plength = floor(log(p)/log(10));// number of digits in the pattern, - 1
pmul = floor(10^plength);// multiplier to get leftmost digit
pdigit = 0;// used for extracted digit
}
void loop(void)
{
pdigit = floor(p / pmul);// rotate pattern one step
p = (p-pdigit*pmul)*10 + pdigit;
if ((pdigit == 1))
{// using first seed
z = z^power + seed1;
}
else if ((pdigit == 2))
{// using second seed
z = z^power + pixel;
}
else
{
// using third seed
z = z^power + pixel;
}
}
bool bailout(void)
{
return(|z| < bailout);
}
void description(void)
{
this.title = "Julia3 Step 1";
this.helpfile = "dmj-pub\dmj-pub-uf-j2.htm";
this.maxiter = 1000;
this.center = (-0.5,0);
seed1.caption = "Julia Seed 1";
seed1.default = (0,0);
seed1.hint = "This is the first Julia seed, a constant parameter which defines the shape of the fractal.";
seedorder.hint = "Selects the order in which the Julia seeds are used. This parameter is retained for compatibility purposes; new fractals should use 'Custom' and set the order explicitly.";
pattern.caption = "Seed Pattern";
pattern.default = 123;
pattern.min = 12;
pattern.hint = "Defines the pattern in which the two seeds will be used. Each digit indicates the seed to use, 1, 2, or 3; when all digits have been used, the pattern repeats. The default of 123 gives the original Julia3 behavior.";
power.caption = "Exponent";
power.default = (2,0);
power.hint = "Overall exponent for the equation. (2,0) gives the classic Julia type.";
bailout.caption = "Bailout";
bailout.default = 1.0e20;
bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Julia3 set anymore.";
}
}
dmj-Julia3-Step2 {
//
// This is the second step in selecting a Julia3 fractal. From
// here, use the Switch feature again to select the third Julia
// point.
//
int p;
parameter real pattern;
parameter int seedorder;
int plength;
int pmul;
int pdigit;
parameter complex power;
parameter complex seed1;
parameter complex seed2;
parameter real bailout;
void init(void)
{
z = 0;
p = pattern;// Starting pattern
if ((seedorder == 0))
{// Preset pattern
p = 123;
}
else if ((seedorder == 1))
{
p = 231;
}
else if ((seedorder == 2))
{
p = 312;
}
else if ((seedorder == 3))
{
p = 321;
}
else if ((seedorder == 4))
{
p = 213;
}
else if ((seedorder == 5))
{
p = 132;
}
plength = floor(log(p)/log(10));// number of digits in the pattern, - 1
pmul = floor(10^plength);// multiplier to get leftmost digit
pdigit = 0;// used for extracted digit
}
void loop(void)
{
pdigit = floor(p / pmul);// rotate pattern one step
p = (p-pdigit*pmul)*10 + pdigit;
if ((pdigit == 1))
{// using first seed
z = z^power + seed1;
}
else if ((pdigit == 2))
{// using second seed
z = z^power + seed2;
}
else
{
// using third seed
z = z^power + pixel;
}
}
bool bailout(void)
{
return(|z| < bailout);
}
void description(void)
{
this.title = "Julia3 Step 2";
this.helpfile = "dmj-pub\dmj-pub-uf-j2.htm";
this.maxiter = 1000;
this.center = (-0.5,0);
seed1.caption = "Julia Seed 1";
seed1.default = (0,0);
seed1.hint = "This is the first Julia seed, a constant parameter which defines the shape of the fractal.";
seed2.caption = "Julia Seed 2";
seed2.default = (0,0);
seed2.hint = "This is the second Julia seed, a constant parameter which defines the shape of the fractal.";
seedorder.hint = "Selects the order in which the Julia seeds are used. This parameter is retained for compatibility purposes; new fractals should use 'Custom' and set the order explicitly.";
pattern.caption = "Seed Pattern";
pattern.default = 123;
pattern.min = 12;
pattern.hint = "Defines the pattern in which the two seeds will be used. Each digit indicates the seed to use, 1, 2, or 3; when all digits have been used, the pattern repeats. The default of 123 gives the original Julia3 behavior.";
power.caption = "Exponent";
power.default = (2,0);
power.hint = "Overall exponent for the equation. (2,0) gives the classic Julia type.";
bailout.caption = "Bailout";
bailout.default = 1.0e20;
bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Julia3 set anymore.";
}
}
dmj-Julia3-Step3 {
//
// This is the final alternating-c Julia3 fractal.
//
int p;
parameter real pattern;
parameter int seedorder;
int plength;
int pmul;
int pdigit;
parameter complex power;
parameter complex seed1;
parameter complex seed2;
parameter complex seed3;
parameter real bailout;
void init(void)
{
z = pixel;
p = pattern;// Starting pattern
if ((seedorder == 0))
{// Preset pattern
p = 123;
}
else if ((seedorder == 1))
{
p = 231;
}
else if ((seedorder == 2))
{
p = 312;
}
else if ((seedorder == 3))
{
p = 321;
}
else if ((seedorder == 4))
{
p = 213;
}
else if ((seedorder == 5))
{
p = 132;
}
plength = floor(log(p)/log(10));// number of digits in the pattern, - 1
pmul = floor(10^plength);// multiplier to get leftmost digit
pdigit = 0;// used for extracted digit
}
void loop(void)
{
pdigit = floor(p / pmul);// rotate pattern one step
p = (p-pdigit*pmul)*10 + pdigit;
if ((pdigit == 1))
{// using first seed
z = z^power + seed1;
}
else if ((pdigit == 2))
{// using second seed
z = z^power + seed2;
}
else
{
// using third seed
z = z^power + seed3;
}
}
bool bailout(void)
{
return(|z| < bailout);
}
void description(void)
{
this.title = "Julia3 Step 3";
this.helpfile = "dmj-pub\dmj-pub-uf-j2.htm";
this.maxiter = 1000;
this.center = (0,0);
seed1.caption = "Julia Seed 1";
seed1.default = (0,0);
seed1.hint = "This is the first Julia seed, a constant parameter which defines the shape of the fractal.";
seed2.caption = "Julia Seed 2";
seed2.default = (0,0);
seed2.hint = "This is the second Julia seed, a constant parameter which defines the shape of the fractal.";
seed3.caption = "Julia Seed 3";
seed3.default = (0,0);
seed3.hint = "This is the third Julia seed, a constant parameter which defines the shape of the fractal.";
seedorder.hint = "Selects the order in which the Julia seeds are used. This parameter is retained for compatibility purposes; new fractals should use 'Custom' and set the order explicitly.";
pattern.caption = "Seed Pattern";
pattern.default = 123;
pattern.min = 12;
pattern.hint = "Defines the pattern in which the two seeds will be used. Each digit indicates the seed to use, 1, 2, or 3; when all digits have been used, the pattern repeats. The default of 123 gives the original Julia3 behavior.";
power.caption = "Exponent";
power.default = (2,0);
power.hint = "Overall exponent for the equation. (2,0) gives the classic Julia type.";
bailout.caption = "Bailout";
bailout.default = 1.0e20;
bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Julia3 set anymore.";
}
}
dmj-LyapMandel {
//
// This fractal iterates the classical Logistics equation,
// but using complex numbers. It is similar to the
// MandelLambda type in FractInt, which is the Mandelbrot
// form of the classic Lambda fractal.
//
parameter complex start;
parameter complex power;
parameter real bailout;
void init(void)
{
z = start;
}
void loop(void)
{
z = pixel*z*(1-z)^(power-1);
}
bool bailout(void)
{
return(|z| < bailout);
}
void description(void)
{
this.title = "Lambda (Mandelbrot)";
this.helpfile = "dmj-pub\dmj-pub-uf-lambda.htm";
this.center = (1,0);
this.magn = 0.5;
start.caption = "Start Value";
start.default = (0.5,0);
start.hint = "Starting value for each point. You can use this to 'perturb' the fractal.";
power.caption = "Exponent";
power.default = (2,0);
power.hint = "Overall exponent for the equation. (2,0) gives the classic Lambda type.";
bailout.caption = "Bailout";
bailout.default = 1.0e20;
bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Lambda set anymore.";
}
}
dmj-LyapJulia {
//
// This fractal iterates the classical Logistics equation,
// but using complex numbers. It is similar to the Lambda
// type in FractInt. Note that all the Julia sets created
// with this formula can be recreated with the classical
// Julia type; however, coloring formulas based on #pixel
// will produce slightly different results, so it is not
// completely redundant.
//
parameter complex seed;
parameter complex power;
parameter real bailout;
void init(void)
{
z = pixel;
}
void loop(void)
{
z = seed*z*(1-z)^(power-1);
}
bool bailout(void)
{
return(|z| < bailout);
}
void description(void)
{
this.title = "Lambda (Julia)";
this.helpfile = "dmj-pub\dmj-pub-uf-lambda.htm";
this.center = (0.5,0);
seed.caption = "Julia Seed";
seed.default = (1,0);
seed.hint = "This is the Julia seed, a constant parameter which defines the shape of the fractal.";
power.caption = "Exponent";
power.default = (2,0);
power.hint = "Overall exponent for the equation. (2,0) gives the classic Julia type.";
bailout.caption = "Bailout";
bailout.default = 1.0e20;
bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Julia set anymore.";
}
}
dmj-Lyapunov {
//
// This is an implementation of Markus-Lyapunov
// fractals, which iterates the classical Logistics
// equation, but varying the (normally constant) r
// value with each iteration, flipping it between
// two values according to a pattern.
//
// This variation allows you to introduce complex
// elements into r, but doing so substantially slows
// down the formula (and it is already slow). So far
// I've not produced any interesting results this way.
//
// This formula is designed to work with the Markus-
// Lyapunov coloring. It also produces only "inside"
// points, so the Outside coloring settings will have
start.hint = "Starting value for each point. You can use this to 'perturb' the fractal.";
seed1.caption = "X Seed";
seed1.default = (0,0);
seed2.caption = "Y Seed";
seed2.default = (0,0);
rotation.caption = "Rotation";
rotation.default = (0,0);
pattern.caption = "Seed Pattern";
pattern.default = 21.0;
pattern.min = 1;
pattern.hint = "Defines the pattern in which the two seeds will be used. Each digit indicates the seed to use, 1 or 2; when all digits have been used, the pattern repeats.";
patterntype.caption = "Seed Pattern Type";
patterntype.default = 0;
patterntype.enum = "decimal\nbinary";
patterntype.hint = "Specifies whether the pattern is expressed in decimals (limited to ten digits) or binary (up to 64 digits).";
offset.caption = "Coloring Offset";
offset.default = 0.0;
offset.hint = "Offsets the coloring value, positive values will cause more areas to be colored.";
power.caption = "Exponent";
power.default = (2,0);
power.hint = "Overall exponent for the equation. (2,0) gives the classic Markus-Lyapunov type.";
filter.caption = "Filter Iterations";
filter.default = 0;
filter.hint = "Specifies the number of iterations to skip before calculating the Markus-Lyapunov exponent.";
start.hint = "Starting value for each point. You can use this to 'perturb' the fractal.";
power.caption = "Exponent";
power.default = (3,0);
power.hint = "Overall exponent for the equation. (3,0) gives the classic NovaM type.";
bailout.caption = "Bailout";
bailout.default = 10000.0;
bailout.hint = "Bailout value; larger values will cause more iterations to be done for each point.";
relax.caption = "Relaxation";
relax.default = (1,0);
relax.hint = "This can be used to slow down the convergence of the formula.";
fudge.caption = "Fudge z Angle";
fudge.default = false;
fudge.hint = "Modifies angle of z based on starting point. Turning this on will make decomposition more consistent between iterations, regardless of the root converged on.";
seed.hint = "This is the Julia seed, a constant parameter which defines the shape of the fractal.";
power.caption = "Exponent";
power.default = (3,0);
power.hint = "Overall exponent for the equation. (3,0) gives the classic NovaM type.";
bailout.caption = "Bailout";
bailout.default = 10000.0;
bailout.hint = "Bailout value; larger values will cause more iterations to be done for each point.";
relax.caption = "Relaxation";
relax.default = (1,0);
relax.hint = "This can be used to slow down the convergence of the formula.";
fudge.caption = "Fudge z Angle";
fudge.default = false;
fudge.hint = "Modifies angle of z based on starting point. Turning this on will make decomposition more consistent between iterations, regardless of the root converged on.";
}
}
dmj-NovaMandel {
//
// This is the Nova fractal (Mandelbrot form), a
// modified Newtonian-style fractal. The formula
// was first shown to me by Paul Derbyshire (who
// named it Nova). It has also appeared elsewhere
// under other names. Use this formula and the
// Switch feature to select a NovaJulia.
//
complex zsquared;
complex zcubed;
complex zold;
parameter complex start;
parameter complex power;
parameter complex relax;
parameter real bailout;
void init(void)
{
zsquared = (0,0);
zcubed = (0,0);
zold = (0,0);
z = start;
}
void loop(void)
{
if ((power == (3,0)))
{// special optimized routine for power 3
zsquared = sqr(z);
zcubed = zsquared * z;
zold = z;
z = z - relax * (zcubed-1) / (3*zsquared) + pixel;
}
else
{
zold = z;
z = z - relax * (z^power-1) / (power * z^(power-1)) + pixel;
}
}
bool bailout(void)
{
return(|z - zold| > bailout);
}
void description(void)
{
this.title = "Nova (Mandelbrot)";
this.helpfile = "dmj-pub\dmj-pub-uf-nova.htm";
this.maxiter = 1000;
this.periodicity = 0;
this.center = (-0.5,0);
this.magn = 1.5;
start.caption = "Start Value";
start.default = (1,0);
start.hint = "Starting value for each point. You can use this to 'perturb' the fractal.";
power.caption = "Exponent";
power.default = (3,0);
power.hint = "Overall exponent for the equation. (3,0) gives the classic NovaM type.";
bailout.caption = "Bailout";
bailout.default = 0.00001;
bailout.hint = "Bailout value; smaller values will cause more iterations to be done for each point.";
relax.caption = "Relaxation";
relax.default = (1,0);
relax.hint = "This can be used to slow down the convergence of the formula.";
}
}
dmj-NovaJulia {
//
// This is the Nova fractal (Julia form), a
// modified Newtonian-style fractal. The formula
// was first shown to me by Paul Derbyshire (who
// named it Nova). It has also appeared elsewhere
// under other names. If you leave the Julia
// seed at the default (0,0), you can use this as
// a general Newton-style fractal as in FractInt.
//
complex zsquared;
complex zcubed;
complex zold;
parameter complex power;
parameter complex relax;
parameter complex seed;
parameter real bailout;
void init(void)
{
zsquared = (0,0);
zcubed = (0,0);
zold = (0,0);
z = pixel;
}
void loop(void)
{
if ((power == (3,0)))
{// special optimized routine for power 3
zsquared = sqr(z);
zcubed = zsquared * z;
zold = z;
z = z - relax * (zcubed-1) / (3*zsquared) + seed;
}
else
{
zold = z;
z = z - relax * (z^power-1) / (power * z^(power-1)) + seed;
}
}
bool bailout(void)
{
return(|z - zold| > bailout);
}
void description(void)
{
this.title = "Nova (Julia)";
this.helpfile = "dmj-pub\dmj-pub-uf-nova.htm";
this.maxiter = 1000;
this.periodicity = 0;
this.center = (0,0);
this.magn = 1.5;
seed.caption = "Julia Seed";
seed.default = (0,0);
seed.hint = "This is the Julia seed, a constant parameter which defines the shape of the fractal.";
power.caption = "Exponent";
power.default = (3,0);
power.hint = "Overall exponent for the equation. (3,0) gives the classic Nova type.";
bailout.caption = "Bailout";
bailout.default = 0.00001;
bailout.hint = "Bailout value; smaller values will cause more iterations to be done for each point.";
relax.caption = "Relaxation";
relax.default = (1,0);
relax.hint = "This can be used to slow down the convergence of the formula.";
}
}
dmj-NovaJulia2-Start {
//
// This is the starting point for Nova Julia2, the
// periodic-c Nova Julia variant. Use UF2's
// Switch feature to select the first Julia point.
//
complex zsquared;
complex zcubed;
complex zold;
parameter complex power;
parameter complex relax;
parameter real bailout;
void init(void)
{
zsquared = (0,0);
zcubed = (0,0);
zold = (0,0);
z = (1,0);
}
void loop(void)
{
if ((power == (3,0)))
{// special optimized routine for power 3
zsquared = sqr(z);
zcubed = zsquared * z;
zold = z;
z = z - relax * (zcubed-1) / (3*zsquared) + pixel;
}
else
{
zold = z;
z = z - relax * (z^power-1) / (power * z^(power-1)) + pixel;
}
}
bool bailout(void)
{
return(|z - zold| > bailout);
}
void description(void)
{
this.title = "Nova Julia2 Start";
this.helpfile = "dmj-pub\dmj-pub-uf-nj2.htm";
this.maxiter = 1000;
this.periodicity = 0;
this.center = (-0.5,0);
this.magn = 1.5;
switchseeds.caption = "Switch Seeds";
switchseeds.default = FALSE;
switchseeds.hint = "If this is enabled, the Julia seeds will be swapped. NOTE: the effects will not be visible at this stage.";
// param pattern
// caption = "Seed Pattern"
// default = 21
// min = 12
// hint = "Defines the pattern in which the two seeds will be used. ; NOTE: the effects will not be visible at this stage."
// endparam
power.caption = "Exponent";
power.default = (3,0);
power.hint = "Overall exponent for the equation. (3,0) gives the classic NovaM type.";
bailout.caption = "Bailout";
bailout.default = 0.00001;
bailout.hint = "Bailout value; smaller values will cause more iterations to be done for each point.";
relax.caption = "Relaxation";
relax.default = (1,0);
relax.hint = "This can be used to slow down the convergence of the formula.";
}
}
dmj-NovaJulia2-Step1 {
//
// This is the first step in selecting a Nova Julia2
// fractal. From here, use the Switch feature again
// to select the second Julia
// point.
//
int count;
complex zold;
complex zold2;
int p;
int plength;
int pmul;
int pdigit;
parameter bool switchseeds;
parameter complex power;
complex zsquared;
complex zcubed;
parameter complex relax;
parameter complex seed1;
parameter real bailout;
void init(void)
{
count = 0;
zold = (0,0);
zold2 = (0,0);
z = (1,0);
p = 21;//@pattern; Starting pattern
plength = floor(log(p)/log(10));// number of digits in the pattern, - 1
pmul = floor(10^plength);// multiplier to get leftmost digit
pdigit = 0;// used for extracted digit
}
void loop(void)
{
pdigit = floor(p / pmul);// rotate pattern one step
p = (p-pdigit*pmul)*10 + pdigit;
if ((switchseeds))
{// seeds should be swapped
pdigit = 3 - pdigit;// use the other seed
}
if ((pdigit == 1))
{// using first seed
if ((power == (3,0)))
{
zsquared = sqr(z);
zcubed = zsquared * z;
z = z - relax * (zcubed-1) / (3*zsquared) + seed1;
}
else
{
z = z - relax * (z^power-1) / (power * z^(power-1)) + seed1;
}
if ((|z - zold| < bailout))
{
count = count + 1;
}
else
{
count = 0;
}
zold = z;
}
else
{
// using second seed
if ((power == (3,0)))
{
zsquared = sqr(z);
zcubed = zsquared * z;
z = z - relax * (zcubed-1) / (3*zsquared) + pixel;
}
else
{
z = z - relax * (z^power-1) / (power * z^(power-1)) + pixel;
}
if ((|z - zold2| < bailout))
{
count = count + 1;
}
else
{
count = 0;
}
zold2 = z;
}
}
bool bailout(void)
{
return(count < plength);
}
void description(void)
{
this.title = "Nova Julia2 Step 1";
this.helpfile = "dmj-pub\dmj-pub-uf-nj2.htm";
this.maxiter = 1000;
this.periodicity = 0;
this.center = (-0.5,0);
this.magn = 1.5;
seed1.caption = "Julia Seed 1";
seed1.default = (0,0);
seed1.hint = "This is the first Julia seed, a constant parameter which defines the shape of the fractal.";
switchseeds.caption = "Switch Seeds";
switchseeds.default = FALSE;
switchseeds.hint = "If this is enabled, the Julia seeds will be swapped. This lets you try the alternate 'flavor' Julia2 without manually swapping the parameters.";
// param pattern
// caption = "Seed Pattern"
// default = 21
// min = 12
// hint = "Defines the pattern in which the two seeds will be used. ; Each digit indicates the seed to use, 1 or 2; when all ; digits have been used, the pattern repeats. The default ; of 21 gives the original Julia2 behavior."
// endparam
power.caption = "Exponent";
power.default = (3,0);
power.hint = "Overall exponent for the equation. (3,0) gives the classic NovaM type.";
bailout.caption = "Bailout";
bailout.default = 0.00001;
bailout.hint = "Bailout value; smaller values will cause more iterations to be done for each point.";
relax.caption = "Relaxation";
relax.default = (1,0);
relax.hint = "This can be used to slow down the convergence of the formula.";
}
}
dmj-NovaJulia2-Step2 {
//
// This is the final alternating-c Nova Julia2 fractal.
// Once both seeds have been selected, you can use
// the Switch feature again to open up a window
// which will let you select the first Julia seed
// again, leaving the second one unchanged.
//
int count;
complex zold;
complex zold2;
int p;
int plength;
int pmul;
int pdigit;
parameter bool switchseeds;
parameter complex power;
complex zsquared;
complex zcubed;
parameter complex relax;
parameter complex seed1;
parameter real bailout;
parameter complex seed2;
void init(void)
{
count = 0;
zold = (0,0);
zold2 = (0,0);
z = pixel;
p = 21;//@pattern; Starting pattern
plength = floor(log(p)/log(10));// number of digits in the pattern, - 1
pmul = floor(10^plength);// multiplier to get leftmost digit
pdigit = 0;// used for extracted digit
}
void loop(void)
{
pdigit = floor(p / pmul);// rotate pattern one step
p = (p-pdigit*pmul)*10 + pdigit;
if ((switchseeds))
{// seeds should be swapped
pdigit = 3 - pdigit;// use the other seed
}
if ((pdigit == 1))
{// using first seed
if ((power == (3,0)))
{
zsquared = sqr(z);
zcubed = zsquared * z;
z = z - relax * (zcubed-1) / (3*zsquared) + seed1;
}
else
{
z = z - relax * (z^power-1) / (power * z^(power-1)) + seed1;
}
if ((|z - zold| < bailout))
{
count = count + 1;
}
else
{
count = 0;
}
zold = z;
}
else
{
// using second seed
if ((power == (3,0)))
{
zsquared = sqr(z);
zcubed = zsquared * z;
z = z - relax * (zcubed-1) / (3*zsquared) + seed2;
}
else
{
z = z - relax * (z^power-1) / (power * z^(power-1)) + seed2;
}
if ((|z - zold2| < bailout))
{
count = count + 1;
}
else if ((count > 0))
{
count = count - 1;
}
zold2 = z;
}
}
bool bailout(void)
{
return(count < plength);
}
void description(void)
{
this.title = "Nova Julia2 Step 2";
this.helpfile = "dmj-pub\dmj-pub-uf-nj2.htm";
this.maxiter = 1000;
this.periodicity = 0;
this.center = (0,0);
this.magn = 1.5;
seed1.caption = "Julia Seed 1";
seed1.default = (0,0);
seed1.hint = "This is the first Julia seed, a constant parameter which defines the shape of the fractal.";
seed2.caption = "Julia Seed 2";
seed2.default = (0,0);
seed2.hint = "This is the second Julia seed, a constant parameter which defines the shape of the fractal.";
switchseeds.caption = "Switch Seeds";
switchseeds.default = FALSE;
switchseeds.hint = "If this is enabled, the Julia seeds will be swapped. This lets you try the alternate 'flavor' Julia2 without manually swapping the parameters.";
// param pattern
// caption = "Seed Pattern"
// default = 21
// min = 12
// hint = "Defines the pattern in which the two seeds will be used. ; Each digit indicates the seed to use, 1 or 2; when all ; digits have been used, the pattern repeats. The default ; of 21 gives the original Julia2 behavior."
// endparam
power.caption = "Exponent";
power.default = (3,0);
power.hint = "Overall exponent for the equation. (3,0) gives the classic Nova type.";
bailout.caption = "Bailout";
bailout.default = 0.00001;
bailout.hint = "Bailout value; smaller values will cause more iterations to be done for each point.";
relax.caption = "Relaxation";
relax.default = (1,0);
relax.hint = "This can be used to slow down the convergence of the formula.";
}
}
dmj-NovaJulia2-Step1a {
//
// This is the first step in selecting a Julia2 fractal. From
// here, use the Switch feature again to select the second Julia
// point.
//
// Note: an early bug in this formula produced erroneous results.
// If you have a parameter set which relied on this behavior,
// please see the obsolete.ufm file.
//
int count;
complex zold;
complex zold2;
int p;
int plength;
int pmul;
int pdigit;
parameter bool switchseeds;
parameter complex power;
complex zsquared;
complex zcubed;
parameter complex relax;
parameter real bailout;
parameter complex seed2;
void init(void)
{
count = 0;
zold = (0,0);
zold2 = (0,0);
z = (1,0);
p = 21;//@pattern; Starting pattern
plength = floor(log(p)/log(10));// number of digits in the pattern, - 1
pmul = floor(10^plength);// multiplier to get leftmost digit
pdigit = 0;// used for extracted digit
}
void loop(void)
{
pdigit = floor(p / pmul);// rotate pattern one step
p = (p-pdigit*pmul)*10 + pdigit;
if ((switchseeds))
{// seeds should be swapped
pdigit = 3 - pdigit;// use the other seed
}
if ((pdigit == 1))
{// using first seed
if ((power == (3,0)))
{
zsquared = sqr(z);
zcubed = zsquared * z;
z = z - relax * (zcubed-1) / (3*zsquared) + pixel;
}
else
{
z = z - relax * (z^power-1) / (power * z^(power-1)) + pixel;
}
if ((|z - zold| < bailout))
{
count = count + 1;
}
else
{
count = 0;
}
zold = z;
}
else
{
// using second seed
if ((power == (3,0)))
{
zsquared = sqr(z);
zcubed = zsquared * z;
z = z - relax * (zcubed-1) / (3*zsquared) + seed2;
}
else
{
z = z - relax * (z^power-1) / (power * z^(power-1)) + seed2;
}
if ((|z - zold2| < bailout))
{
count = count + 1;
}
else
{
count = 0;
}
zold2 = z;
}
}
bool bailout(void)
{
return(count < plength);
}
void description(void)
{
this.title = "Nova Julia2 Step 1a";
this.helpfile = "dmj-pub\dmj-pub-uf-nj2.htm";
this.maxiter = 1000;
this.periodicity = 0;
this.center = (-0.5,0);
this.magn = 1.5;
seed2.caption = "Julia Seed 2";
seed2.default = (0,0);
seed2.hint = "This is the second Julia seed, a constant parameter which defines the shape of the fractal.";
switchseeds.caption = "Switch Seeds";
switchseeds.default = FALSE;
switchseeds.hint = "If this is enabled, the Julia seeds will be swapped. This lets you try the alternate 'flavor' Julia2 without manually swapping the parameters.";
// param pattern
// caption = "Seed Pattern"
// default = 21
// min = 12
// hint = "Defines the pattern in which the two seeds will be used. ; Each digit indicates the seed to use, 1 or 2; when all ; digits have been used, the pattern repeats. The default ; of 21 gives the original Julia2 behavior."
// endparam
power.caption = "Exponent";
power.default = (3,0);
power.hint = "Overall exponent for the equation. (3,0) gives the classic NovaM type.";
bailout.caption = "Bailout";
bailout.default = 0.00001;
bailout.hint = "Bailout value; smaller values will cause more iterations to be done for each point.";
relax.caption = "Relaxation";
relax.default = (1,0);
relax.hint = "This can be used to slow down the convergence of the formula.";
}
}
dmj-PhoenixMandel {
//
// This type implements the Phoenix types discovered by
// Shigehiro Ushiki. It is somewhat generalized over
// the FractInt implementation. The general equation is
// of the form
//
// z(n+1) = z(n)^a + c*z(n)^b + p*z(n-1)
//
// In FractInt, choices for b are restricted to a-1 and
// a-2. This implementation allows arbitrary choices
// for both a and b.
//
// If a=2 and b=0 (classic Phoenix) then this type will
// work with the dmj-Smooth and dmj-Triangle coloring
xfer.hint = "This function will be applied to the height value before a slope is calculated.";
zscale.caption = "Height Pre-Scale";
zscale.default = 1.0;
zscale.hint = "Specifies the ratio between height and distance. Higher values will exaggerate differences between high and low. In general, you will want to use smaller numbers here.";
zscale2.caption = "Height Post-Scale";
zscale2.default = 0.025;
zscale2.hint = "Specifies the ratio between height and distance; like Height Pre-Scale, except that this value is applied after the transfer function.";
everyiter.caption = "Every Iteration";
everyiter.default = false;
everyiter.hint = "If set, the surface normal will be computed at every iteration. If you are using a coloring algorithm which processes every iteration, you will need this.";
}
}
dmj-SlopeLyapJulia {
//
// This is the LambdaJulia set, but the calculations
// are modified so that z contains a surface normal
// to the set instead of the orbit value. This is
// intended primarily for the Lighting coloring
// method, but might have interesting results for
// other methods, too.
//
complex z1;
complex z2;
parameter real offset;
complex z3;
int done;
real modz;
real il2;
parameter complex power;
real lp;
parameter real bailout;
real e1;
real e2;
real e3;
real vx;
real vy;
real vz;
real vd;
real d1;
real d2;
real d3;
real s1;
complex e20;
real s2;
real s3;
complex g1;
complex g2;
complex g3;
complex o1;
complex o2;
complex o3;
parameter complex seed;
parameter int zmode;
parameter bool everyiter;
parameter real zscale;
parameter int xfer;
parameter real zscale2;
void init(void)
{
z1 = pixel;// primary iterated point
z2 = pixel + offset;// horizontally offset point
z3 = pixel + flip(offset);// vertically offset point
xfer.hint = "This function will be applied to the height value before a slope is calculated.";
zscale.caption = "Height Pre-Scale";
zscale.default = 1.0;
zscale.hint = "Specifies the ratio between height and distance. Higher values will exaggerate differences between high and low. In general, you will want to use smaller numbers here.";
zscale2.caption = "Height Post-Scale";
zscale2.default = 0.025;
zscale2.hint = "Specifies the ratio between height and distance; like Height Pre-Scale, except that this value is applied after the transfer function.";
everyiter.caption = "Every Iteration";
everyiter.default = false;
everyiter.hint = "If set, the surface normal will be computed at every iteration. If you are using a coloring algorithm which processes every iteration, you will need this.";
}
}
dmj-SlopeMandel {
//
// This is the Mandelbrot set, but the calculations
// are modified so that z contains a surface normal
// to the set instead of the orbit value. This is
// intended primarily for the Lighting coloring
// method, but might have interesting results for
// other methods, too.
//
complex c1;
complex c2;
parameter real offset;
complex c3;
complex z1;
parameter complex start;
complex z2;
complex z3;
int done;
real modz;
real il2;
parameter complex power;
real lp;
parameter real bailout;
real e1;
real e2;
real e3;
real vx;
real vy;
real vz;
real vd;
real d1;
real d2;
real d3;
real s1;
complex e20;
real s2;
real s3;
complex g1;
complex g2;
complex g3;
complex o1;
complex o2;
complex o3;
parameter int zmode;
parameter bool everyiter;
parameter real zscale;
parameter int xfer;
parameter real zscale2;
void init(void)
{
c1 = pixel;// primary iterated point
c2 = pixel + offset;// horizontally offset point
c3 = pixel + flip(offset);// vertically offset point
xfer.hint = "This function will be applied to the height value before a slope is calculated.";
zscale.caption = "Height Pre-Scale";
zscale.default = 1.0;
zscale.hint = "Specifies the ratio between height and distance. Higher values will exaggerate differences between high and low. In general, you will want to use smaller numbers here.";
zscale2.caption = "Height Post-Scale";
zscale2.default = 0.025;
zscale2.hint = "Specifies the ratio between height and distance; like Height Pre-Scale, except that this value is applied after the transfer function.";
everyiter.caption = "Every Iteration";
everyiter.default = false;
everyiter.hint = "If set, the surface normal will be computed at every iteration. If you are using a coloring algorithm which processes every iteration, you will need this.";
}
}
dmj-SlopeJulia {
//
// This is the Julia set, but the calculations
// are modified so that z contains a surface normal
// to the set instead of the orbit value. This is
// intended primarily for the Lighting coloring
// method, but might have interesting results for
// other methods, too.
//
complex z1;
complex z2;
parameter real offset;
complex z3;
int done;
real modz;
real il2;
parameter complex power;
real lp;
parameter real bailout;
real e1;
real e2;
real e3;
real vx;
real vy;
real vz;
real vd;
real d1;
real d2;
real d3;
real s1;
complex e20;
real s2;
real s3;
complex g1;
complex g2;
complex g3;
complex o1;
complex o2;
complex o3;
parameter complex seed;
parameter int zmode;
parameter bool everyiter;
parameter real zscale;
parameter int xfer;
parameter real zscale2;
void init(void)
{
z1 = pixel;// primary iterated point
z2 = pixel + offset;// horizontally offset point
z3 = pixel + flip(offset);// vertically offset point
xfer.hint = "This function will be applied to the height value before a slope is calculated.";
zscale.caption = "Height Pre-Scale";
zscale.default = 1.0;
zscale.hint = "Specifies the ratio between height and distance. Higher values will exaggerate differences between high and low. In general, you will want to use smaller numbers here.";
zscale2.caption = "Height Post-Scale";
zscale2.default = 0.025;
zscale2.hint = "Specifies the ratio between height and distance; like Height Pre-Scale, except that this value is applied after the transfer function.";
everyiter.caption = "Every Iteration";
everyiter.default = false;
everyiter.hint = "If set, the surface normal will be computed at every iteration. If you are using a coloring algorithm which processes every iteration, you will need this.";
}
}
dmj-SlopeJulia2 {
//
// This is the Julia2 set, but the calculations
// are modified so that z contains a surface normal
// to the set instead of the orbit value. This is
// intended primarily for the Lighting coloring
// method, but might have interesting results for
// other methods, too.
//
int p;
parameter real pattern;
int plength;
int pmul;
int pdigit;
bool t;
parameter bool switchseeds;
complex z1;
complex z2;
parameter real offset;
complex z3;
int done;
real modz;
real il2;
parameter complex power;
real lp;
parameter real bailout;
real e1;
real e2;
real e3;
real vx;
real vy;
real vz;
real vd;
real d1;
real d2;
real d3;
real s1;
complex e20;
real s2;
real s3;
complex g1;
complex g2;
complex g3;
complex o1;
complex o2;
complex o3;
parameter complex seed2;
parameter complex seed1;
parameter int zmode;
parameter bool everyiter;
parameter real zscale;
parameter int xfer;
parameter real zscale2;
void init(void)
{
p = pattern;// Starting pattern
plength = floor(log(p)/log(10));// number of digits in the pattern, - 1
pmul = floor(10^plength);// multiplier to get leftmost digit
pdigit = 0;// used for extracted digit
t = false;
if ((p == 21 && switchseeds))
{// special optimized pattern
t = true;// start with the other seed
}
z1 = pixel;// primary iterated point
z2 = pixel + offset;// horizontally offset point
z3 = pixel + flip(offset);// vertically offset point
z = z1;// use primary iteration value to keep periodicity working
}
if ((modz > bailout))
{// we're done
done = 0;
}
}
bool bailout(void)
{
return((done > 0));
}
void description(void)
{
this.title = "Slope (Julia2)";
this.helpfile = "dmj-pub\dmj-pub-uf-slope.htm";
this.center = (0.0, 0.0);
this.maxiter = 1000;
seed1.caption = "Julia Seed 1";
seed1.default = (0,0);
seed1.hint = "This is the first Julia seed, a constant parameter which defines the shape of the fractal.";
seed2.caption = "Julia Seed 2";
seed2.default = (0,0);
seed2.hint = "This is the second Julia seed, a constant parameter which defines the shape of the fractal.";
switchseeds.caption = "Switch Seeds";
switchseeds.default = FALSE;
switchseeds.hint = "If this is enabled, the Julia seeds will be swapped. This lets you try the alternate 'flavor' Julia2 without manually swapping the parameters.";
pattern.caption = "Seed Pattern";
pattern.default = 21;
pattern.min = 12;
pattern.hint = "Defines the pattern in which the two seeds will be used. Each digit indicates the seed to use, 1 or 2; when all digits have been used, the pattern repeats. The default of 21 gives the original Julia2 behavior.";
power.caption = "Exponent";
power.default = (2,0);
power.hint = "Overall exponent for the equation. (2,0) gives the classic Julia type.";
bailout.caption = "Bail-out Value";
bailout.default = 1.0e20;
bailout.min = 0.0;
bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Julia set anymore.";
offset.caption = "Orbit Separation";
offset.default = 0.00000001;
offset.hint = "Defines how far apart the simultaneous orbits are. Smaller distances will produce more accurate results.";
xfer.hint = "This function will be applied to the height value before a slope is calculated.";
zscale.caption = "Height Pre-Scale";
zscale.default = 1.0;
zscale.hint = "Specifies the ratio between height and distance. Higher values will exaggerate differences between high and low. In general, you will want to use smaller numbers here.";
zscale2.caption = "Height Post-Scale";
zscale2.default = 0.025;
zscale2.hint = "Specifies the ratio between height and distance; like Height Pre-Scale, except that this value is applied after the transfer function.";
everyiter.caption = "Every Iteration";
everyiter.default = false;
everyiter.hint = "If set, the surface normal will be computed at every iteration. If you are using a coloring algorithm which processes every iteration, you will need this.";
}
}
dmj-Slope2Mandel {
//
// This is the Mandelbrot set, but the calculations
// are modified so that z contains a surface normal
// to the set instead of the orbit value. This is
// intended primarily for the Lighting coloring
// method, but might have interesting results for
// other methods, too.
//
complex c1;
complex c2;
parameter real offset;
complex c3;
complex z1;
parameter complex start;
complex z2;
complex z3;
real modz;
real e1;
real e2;
real e3;
real vx;
real vy;
real vz;
real vd;
int j;
real closest;
complex e38;
real closest1;
real d;
real d2;
complex point;
complex point1;
complex point2;
complex point3;
complex zT;
complex zP;
complex cT;
bool done;
int i;
int i1;
int iter;
real fiter;
parameter real trapstart;
bool trapping;
real diameter2;
parameter real diameter;
real r1;
parameter real Parm_angle;
real r2;
parameter real anglestep;
real s1;
parameter real skew;
real s2;
parameter real skewstep;
complex r;
complex r0;
complex s;
complex rh;
parameter real traporder;
complex zh;
complex trapcenter2;
parameter complex trapcenter;
parameter bool movetrap;
parameter int trapshape;
parameter int traptype;
int z1i;
int z2i;
int z3i;
int z1i1;
int z2i1;
int z3i1;
real z1closest;
real z2closest;
real z3closest;
real z1closest1;
real z2closest1;
real z3closest1;
complex z1point;
complex z2point;
complex z3point;
complex z1point1;
complex z2point1;
complex z3point1;
complex z1point2;
complex z2point2;
complex z3point2;
complex z1point3;
complex z2point3;
complex z3point3;
parameter complex power;
parameter real trapskip;
parameter real trapiter;
parameter complex trapdrift;
parameter complex traporbit;
parameter real gausss;
parameter real gaussr;
parameter complex gausscenter;
parameter int radialmode;
parameter real gauss;
parameter complex gaussgcenter;
parameter real aspect;
parameter real trapfreq;
parameter real prescale;
parameter int trapfunc;
parameter real postscale;
parameter bool trapabs;
parameter real threshold;
parameter real bailout;
parameter bool everyiter;
parameter int trapcolor;
parameter real zscale;
parameter int xfer;
parameter real zscale2;
void init(void)
{
c1 = pixel;// primary iterated point
c2 = pixel + offset;// horizontally offset point
c3 = pixel + flip(offset);// vertically offset point
trapshape.hint = "This is the shape of the orbit trap.";
trapcolor.caption = "Trap Coloring";
trapcolor.default = 0;
trapcolor.enum = "distance\nmagnitude\nreal\nimaginary\nangle to trap\nangle to trap 2\nangle to origin\nangle to origin 2\niteration";
trapcolor.hint = "This is the information used to produce a color.";
traptype.caption = "Trap Mode";
traptype.default = 0;
traptype.enum = "closest\nfarthest\nfirst\nlast\nsum\naverage\nproduct\nsign average\nsecond closest\nsecond farthest\ntwo closest\ntwo farthest\nfunky average\nfunky average 2\nfunky average 3\nfunky average 4\nfunky average 5\nfunky average 6\ntrap only";
traptype.hint = "This is how points will be chosen to use for coloring.";
traporder.caption = "Trap Order";
traporder.default = 4.0;
traporder.hint = "Number of leaves for the pinch trap shape, the exponent to use for astroid curves (try 0.66667), 'egginess', or the height of waves.";
trapfreq.caption = "Trap Frequency";
trapfreq.default = 1.0;
trapfreq.hint = "The frequency of ripples or waves.";
trapcenter.caption = "Trap Center";
trapcenter.default = (0,0);
trapcenter.hint = "This is the location of the trap in the complex plane.";
trapdrift.caption = "Trap Drift";
trapdrift.default = (0,0);
trapdrift.hint = "This is the amount the trap center will move with each iteration.";
traporbit.caption = "Trap Orbit";
traporbit.default = (0,0);
traporbit.hint = "The trap center location is multiplied by this value with each iteration.";
movetrap.caption = "Trap Center Moves";
movetrap.default = false;
movetrap.hint = "If this is enabled, the trap center will match the pixel location instead of being fixed. This overrides Trap Center.";
aspect.caption = "Aspect Ratio";
aspect.default = 1.0;
aspect.min = 0.0000000001;
aspect.hint = "This is how square the trap is. You can distort the trap by using a value other than 1.0.";
threshold.caption = "Threshold";
threshold.default = 0.25;
threshold.min = 0;
threshold.hint = "This is the width of the trap area, used for most trap modes.";
diameter.caption = "Diameter";
diameter.default = 1.0;
// min = 0
diameter.hint = "This is the diameter of the trap (for ring, box, and line shapes).";
Parm_angle.caption = "Rotation";
Parm_angle.default = 0.0;
Parm_angle.hint = "This is the angle, in degrees, that the trap should be rotated.";
anglestep.caption = "Rotation Step";
anglestep.default = 0.0;
anglestep.hint = "This is the angle, in degrees, that the trap will be rotated with each iteration.";
skew.caption = "Skew";
skew.default = 0.0;
skew.hint = "This is the angle, in degrees, to skew the vertical axis of the trap shape.";
skewstep.caption = "Skew Step";
skewstep.default = 0.0;
skewstep.hint = "This is the angle, in degrees, that the skew angle should be increased by with each iteration.";
trapfunc.hint = "This function is applied to trap distances at every iteration. It can be used to apply some special effects to trap shapes.";
prescale.caption = "Distance Pre-scale";
prescale.default = 1.0;
prescale.hint = "This is a multiplier applied to the trap distance, before the Distance Transfer function is applied to it.";
postscale.caption = "Distance Post-scale";
postscale.default = 1.0;
postscale.hint = "This is a multiplier applied to the trap distance, after the Distance Transfer function is applied to it.";
trapabs.caption = "No Negative Distance";
trapabs.default = false;
trapabs.hint = "If enabled, eliminates 'negative' distances by taking the absolute value of the distance.";
trapstart.caption = "Start Iteration";
trapstart.default = 0.0;
trapstart.hint = "This is the iteration at which to start watching for orbit traps.";
trapiter.caption = "Trap Iterations";
trapiter.default = 10000.0;
trapiter.hint = "This is the number of iterations to watch for traps in a single block.";
trapskip.caption = "Skip Iterations";
trapskip.default = 0.0;
trapskip.hint = "This is the number of iterations to skip watching for traps, after a block of watched iterations.";
gauss.caption = "Repeat Spacing";
gauss.default = 0.0;
gauss.min = 0.0;
gauss.hint = "This is the spacing at which the trap will repeat, all across the complex plane. If zero, trap does not repeat.";
gaussgcenter.caption = "Repeat Center";
gaussgcenter.default = (0,0);
gaussgcenter.hint = "This is the center point of grid trap repetition.";
gaussr.caption = "Radial Spacing";
gaussr.default = 0.0;
gaussr.min = 0;
gaussr.hint = "This is the number of times the trap will repeat, radially around the radial center point. If zero, trap does not repeat radially.";
gausss.caption = "Concentric Spacing";
gausss.default = 0.0;
gausss.min = 0;
gausss.hint = "This is the distance at which the trap will repeat, radially out from the radial center point. If zero, trap does not repeat radially out.";
gausscenter.caption = "Radial Center";
gausscenter.default = (0,0);
gausscenter.hint = "This is the center point of radial trap repetition.";
xfer.hint = "This function will be applied to the height value before a slope is calculated.";
zscale.caption = "Height Pre-Scale";
zscale.default = 1.0;
zscale.hint = "Specifies the ratio between height and distance. Higher values will exaggerate differences between high and low. In general, you will want to use smaller numbers here.";
zscale2.caption = "Height Post-Scale";
zscale2.default = 0.025;
zscale2.hint = "Specifies the ratio between height and distance; like Height Pre-Scale, except that this value is applied after the transfer function.";
everyiter.caption = "Every Iteration";
everyiter.default = false;
everyiter.hint = "If set, the surface normal will be computed at every iteration. If you are using a coloring algorithm which processes every iteration, you will need this.";
}
}
dmj-Slope2Julia {
//
// This is the Julia set, but the calculations
// are modified so that z contains a surface normal
// to the set instead of the orbit value. This is
// intended primarily for the Lighting coloring
// method, but might have interesting results for
// other methods, too.
//
complex z1;
complex z2;
parameter real offset;
complex z3;
real modz;
real e1;
real e2;
real e3;
real vx;
real vy;
real vz;
real vd;
int j;
real closest;
complex e38;
real closest1;
real d;
real d2;
complex point;
complex point1;
complex point2;
complex point3;
complex zT;
complex zP;
complex cT;
bool done;
int i;
int i1;
int iter;
real fiter;
parameter real trapstart;
bool trapping;
real diameter2;
parameter real diameter;
real r1;
parameter real Parm_angle;
real r2;
parameter real anglestep;
real s1;
parameter real skew;
real s2;
parameter real skewstep;
complex r;
complex r0;
complex s;
complex rh;
parameter real traporder;
complex zh;
complex trapcenter2;
parameter complex trapcenter;
parameter bool movetrap;
parameter int trapshape;
parameter int traptype;
int z1i;
int z2i;
int z3i;
int z1i1;
int z2i1;
int z3i1;
real z1closest;
real z2closest;
real z3closest;
real z1closest1;
real z2closest1;
real z3closest1;
complex z1point;
complex z2point;
complex z3point;
complex z1point1;
complex z2point1;
complex z3point1;
complex z1point2;
complex z2point2;
complex z3point2;
complex z1point3;
complex z2point3;
complex z3point3;
parameter complex power;
parameter complex seed;
parameter real trapskip;
parameter real trapiter;
parameter complex trapdrift;
parameter complex traporbit;
parameter real gausss;
parameter real gaussr;
parameter complex gausscenter;
parameter int radialmode;
parameter real gauss;
parameter complex gaussgcenter;
parameter real aspect;
parameter real trapfreq;
parameter real prescale;
parameter int trapfunc;
parameter real postscale;
parameter bool trapabs;
parameter real threshold;
parameter real bailout;
parameter bool everyiter;
parameter int trapcolor;
parameter real zscale;
parameter int xfer;
parameter real zscale2;
void init(void)
{
z1 = pixel;// primary iterated point
z2 = pixel + offset;// horizontally offset point
z3 = pixel + flip(offset);// vertically offset point
trapshape.hint = "This is the shape of the orbit trap.";
trapcolor.caption = "Trap Coloring";
trapcolor.default = 0;
trapcolor.enum = "distance\nmagnitude\nreal\nimaginary\nangle to trap\nangle to trap 2\nangle to origin\nangle to origin 2\niteration";
trapcolor.hint = "This is the information used to produce a color.";
traptype.caption = "Trap Mode";
traptype.default = 0;
traptype.enum = "closest\nfarthest\nfirst\nlast\nsum\naverage\nproduct\nsign average\nsecond closest\nsecond farthest\ntwo closest\ntwo farthest\nfunky average\nfunky average 2\nfunky average 3\nfunky average 4\nfunky average 5\nfunky average 6\ntrap only";
traptype.hint = "This is how points will be chosen to use for coloring.";
traporder.caption = "Trap Order";
traporder.default = 4.0;
traporder.hint = "Number of leaves for the pinch trap shape, the exponent to use for astroid curves (try 0.66667), 'egginess', or the height of waves.";
trapfreq.caption = "Trap Frequency";
trapfreq.default = 1.0;
trapfreq.hint = "The frequency of ripples or waves.";
trapcenter.caption = "Trap Center";
trapcenter.default = (0,0);
trapcenter.hint = "This is the location of the trap in the complex plane.";
trapdrift.caption = "Trap Drift";
trapdrift.default = (0,0);
trapdrift.hint = "This is the amount the trap center will move with each iteration.";
traporbit.caption = "Trap Orbit";
traporbit.default = (0,0);
traporbit.hint = "The trap center location is multiplied by this value with each iteration.";
movetrap.caption = "Trap Center Moves";
movetrap.default = false;
movetrap.hint = "If this is enabled, the trap center will match the pixel location instead of being fixed. This overrides Trap Center.";
aspect.caption = "Aspect Ratio";
aspect.default = 1.0;
aspect.min = 0.0000000001;
aspect.hint = "This is how square the trap is. You can distort the trap by using a value other than 1.0.";
threshold.caption = "Threshold";
threshold.default = 0.25;
threshold.min = 0;
threshold.hint = "This is the width of the trap area, used for most trap modes.";
diameter.caption = "Diameter";
diameter.default = 1.0;
// min = 0
diameter.hint = "This is the diameter of the trap (for ring, box, and line shapes).";
Parm_angle.caption = "Rotation";
Parm_angle.default = 0.0;
Parm_angle.hint = "This is the angle, in degrees, that the trap should be rotated.";
anglestep.caption = "Rotation Step";
anglestep.default = 0.0;
anglestep.hint = "This is the angle, in degrees, that the trap will be rotated with each iteration.";
skew.caption = "Skew";
skew.default = 0.0;
skew.hint = "This is the angle, in degrees, to skew the vertical axis of the trap shape.";
skewstep.caption = "Skew Step";
skewstep.default = 0.0;
skewstep.hint = "This is the angle, in degrees, that the skew angle should be increased by with each iteration.";
trapfunc.hint = "This function is applied to trap distances at every iteration. It can be used to apply some special effects to trap shapes.";
prescale.caption = "Distance Pre-scale";
prescale.default = 1.0;
prescale.hint = "This is a multiplier applied to the trap distance, before the Distance Transfer function is applied to it.";
postscale.caption = "Distance Post-scale";
postscale.default = 1.0;
postscale.hint = "This is a multiplier applied to the trap distance, after the Distance Transfer function is applied to it.";
trapabs.caption = "No Negative Distance";
trapabs.default = false;
trapabs.hint = "If enabled, eliminates 'negative' distances by taking the absolute value of the distance.";
trapstart.caption = "Start Iteration";
trapstart.default = 0.0;
trapstart.hint = "This is the iteration at which to start watching for orbit traps.";
trapiter.caption = "Trap Iterations";
trapiter.default = 10000.0;
trapiter.hint = "This is the number of iterations to watch for traps in a single block.";
trapskip.caption = "Skip Iterations";
trapskip.default = 0.0;
trapskip.hint = "This is the number of iterations to skip watching for traps, after a block of watched iterations.";
gauss.caption = "Repeat Spacing";
gauss.default = 0.0;
gauss.min = 0.0;
gauss.hint = "This is the spacing at which the trap will repeat, all across the complex plane. If zero, trap does not repeat.";
gaussgcenter.caption = "Repeat Center";
gaussgcenter.default = (0,0);
gaussgcenter.hint = "This is the center point of grid trap repetition.";
gaussr.caption = "Radial Spacing";
gaussr.default = 0.0;
gaussr.min = 0;
gaussr.hint = "This is the number of times the trap will repeat, radially around the radial center point. If zero, trap does not repeat radially.";
gausss.caption = "Concentric Spacing";
gausss.default = 0.0;
gausss.min = 0;
gausss.hint = "This is the distance at which the trap will repeat, radially out from the radial center point. If zero, trap does not repeat radially out.";
gausscenter.caption = "Radial Center";
gausscenter.default = (0,0);
gausscenter.hint = "This is the center point of radial trap repetition.";
xfer.hint = "This function will be applied to the height value before a slope is calculated.";
zscale.caption = "Height Pre-Scale";
zscale.default = 1.0;
zscale.hint = "Specifies the ratio between height and distance. Higher values will exaggerate differences between high and low. In general, you will want to use smaller numbers here.";
zscale2.caption = "Height Post-Scale";
zscale2.default = 0.025;
zscale2.hint = "Specifies the ratio between height and distance; like Height Pre-Scale, except that this value is applied after the transfer function.";
everyiter.caption = "Every Iteration";
everyiter.default = false;
everyiter.hint = "If set, the surface normal will be computed at every iteration. If you are using a coloring algorithm which processes every iteration, you will need this.";
}
}
dmj-SNovaMandel {
//
// This is the SinNova fractal (Mandelbrot form), a
// modified Newtonian-style fractal. The formula
// was first shown to me by Paul Derbyshire (who
// named it Nova). It has also appeared elsewhere
// under other names. Use this formula and the
// Switch feature to select a NovaJulia.
//
complex zold;
parameter complex start;
parameter complex relax;
parameter complex power;
parameter real bailout;
void init(void)
{
zold = (0,0);
z = start;
}
void loop(void)
{
zold = z;
z = z - relax * (sin(z)^power-1) / (power * sin(z)^(power-1) * cos(z)) + pixel;
}
bool bailout(void)
{
return(|z - zold| > bailout);
}
void description(void)
{
this.title = "SinNova (Mandelbrot)";
this.helpfile = "dmj-pub\dmj-pub-uf-sn.htm";
this.maxiter = 1000;
this.periodicity = 0;
this.center = (-0.5,0);
this.magn = 1.5;
start.caption = "Start Value";
start.default = (1,0);
start.hint = "Starting value for each point. You can use this to 'perturb' the fractal.";
power.caption = "Exponent";
power.default = (3,0);
power.hint = "Overall exponent for the equation. (3,0) gives the classic NovaM type.";
bailout.caption = "Bailout";
bailout.default = 0.00001;
bailout.hint = "Bailout value; smaller values will cause more iterations to be done for each point.";
relax.caption = "Relaxation";
relax.default = (1,0);
relax.hint = "This can be used to slow down the convergence of the formula.";
}
}
dmj-SNovaJulia {
//
// This is the SinNova fractal (Julia form), a
// modified Newtonian-style fractal. The formula
// was first shown to me by Paul Derbyshire (who
// named it Nova). It has also appeared elsewhere
// under other names. If you leave the Julia
// seed at the default (0,0), you can use this as
// a general Newton-style fractal as in FractInt.
//
complex zold;
parameter complex relax;
parameter complex power;
parameter complex seed;
parameter real bailout;
void init(void)
{
zold = (0,0);
z = pixel;
}
void loop(void)
{
zold = z;
z = z - relax * (sin(z)^power-1) / (power * sin(z)^(power-1) * cos(z)) + seed;
}
bool bailout(void)
{
return(|z - zold| > bailout);
}
void description(void)
{
this.title = "SinNova (Julia)";
this.helpfile = "dmj-pub\dmj-pub-uf-sn.htm";
this.maxiter = 1000;
this.periodicity = 0;
this.center = (0,0);
this.magn = 1.5;
seed.caption = "Julia Seed";
seed.default = (0,0);
seed.hint = "This is the Julia seed, a constant parameter which defines the shape of the fractal.";
power.caption = "Exponent";
power.default = (3,0);
power.hint = "Overall exponent for the equation. (3,0) gives the classic Nova type.";
bailout.caption = "Bailout";
bailout.default = 0.00001;
bailout.hint = "Bailout value; smaller values will cause more iterations to be done for each point.";
relax.caption = "Relaxation";
relax.default = (1,0);
relax.hint = "This can be used to slow down the convergence of the formula.";
}
}
dmj-StutterMandel {
//
// I got this idea while looking at '99 contest entries.
// The essential idea is to perform a normal Mandelbrot
// iteration for a while, and then "reset" the calculation,
// using the current z as a new c and then setting z back
// to the start value.
//
parameter complex start;
complex c;
real f;
parameter real restart;
parameter complex power;
parameter real bailout;
void init(void)
{
z = start;
c = pixel;
f = restart;
}
void loop(void)
{
f = f - 1;
if ((f <= 0))
{
f = f + restart;
c = z;
z = start;
}
z = z^power + c;
}
bool bailout(void)
{
return(|z| < bailout);
}
void description(void)
{
this.title = "StutterMandel";
this.helpfile = "dmj-pub\dmj-pub-uf-stutter.htm";
this.center = (-0.5,0);
this.periodicity = 0;
this.maxiter = 1000;
start.caption = "Start Value";
start.default = (0,0);
start.hint = "Starting value for each point. You can use this to 'perturb' the fractal.";
power.caption = "Exponent";
power.default = (2,0);
power.hint = "Overall exponent for the equation. (2,0) gives the classic Mandelbrot type.";
bailout.caption = "Bailout";
bailout.default = 1e20;
bailout.hint = "Bailout value; larger values will cause more iterations to be done for each point.";
restart.caption = "Restart Interval";
restart.default = 16.0;
restart.min = 1e-10;
restart.hint = "Specifies the number of iterations before c is reset.";
}
}
dmj-TorusMandel {
//
// This is a simple implementation of Earl Hinrichs'
// torus-method renderings of the 4D Julibrot fractal.
// Don't try to wrap your head around the 4D torus
// shape, it will cause you pain. :) Just keep in mind
// that each image axis represents a circle in 4D
// space that is perpendicular to the circle used for
// the other image axis.
//
// These images naturally repeat. With the right
// settings, you can make tileable images with them.
//
complex c;
parameter complex scale1;
parameter complex scale2;
parameter complex power;
parameter real bailout;
void init(void)
{
c = (0,1)^(imag(pixel));
z = (0,1)^(real(pixel));
z = real(z)*real(scale1) + flip(imag(z)*imag(scale1));
c = real(c)*real(scale2) + flip(imag(c)*imag(scale2));
}
void loop(void)
{
z = z^power + c;
}
bool bailout(void)
{
return(|z| < bailout);
}
void description(void)
{
this.title = "Torus (Julibrot)";
this.helpfile = "dmj-pub\dmj-pub-uf-tj.htm";
this.maxiter = 1000;
this.center = (0,0);
this.magn = 1.0;
power.caption = "Exponent";
power.default = (2,0);
power.hint = "Overall exponent for the equation. (2,0) gives the classic Mandelbrot type.";
bailout.caption = "Bailout";
bailout.default = 1.0e20;
bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Mandelbrot set anymore.";
scale1.caption = "Ring 1 Scale";
scale1.default = (1.0,1.0);
scale1.hint = "Sets the width and height of the ring used for the real axis, carved through z space.";
scale2.caption = "Ring 2 Scale";
scale2.default = (1.0,1.0);
scale2.hint = "Sets the width and height of the ring used for the imaginary axis, carved through c space.";
}
}
dmj-TorusNova {
//
// This is a simple implementation of Earl Hinrichs'
// torus-method renderings of the 4D NovaM/J fractal.
// Don't try to wrap your head around the 4D torus
// shape, it will cause you pain. :) Just keep in mind
// that each image axis represents a circle in 4D
// space that is perpendicular to the circle used for
// the other image axis.
//
// These images naturally repeat. With the right
// settings, you can make tileable images with them.
//
complex c;
parameter complex scale1;
parameter complex scale2;
complex zsquared;
complex zcubed;
complex zold;
parameter complex power;
parameter complex relax;
parameter real bailout;
void init(void)
{
c = (0,1)^(imag(pixel));
z = (0,1)^(real(pixel));
z = real(z)*real(scale1) + flip(imag(z)*imag(scale1));
c = real(c)*real(scale2) + flip(imag(c)*imag(scale2));
zsquared = (0,0);
zcubed = (0,0);
zold = (0,0);
}
void loop(void)
{
if ((power == (3,0)))
{// special optimized routine for power 3
zsquared = sqr(z);
zcubed = zsquared * z;
zold = z;
z = z - relax * (zcubed-1) / (3*zsquared) + c;
}
else
{
zold = z;
z = z - relax * (z^power-1) / (power * z^(power-1)) + c;
}
}
bool bailout(void)
{
return(|z-zold| > bailout);
}
void description(void)
{
this.title = "Torus (Nova)";
this.helpfile = "dmj-pub\dmj-pub-uf-tn.htm";
this.maxiter = 1000;
this.periodicity = 0;
this.center = (0,0);
this.magn = 1.0;
power.caption = "Exponent";
power.default = (3,0);
power.hint = "Overall exponent for the equation. (3,0) gives the classic NovaM type.";
bailout.caption = "Bailout";
bailout.default = 0.00001;
bailout.hint = "Bailout value; smaller values will cause more iterations to be done for each point.";
relax.caption = "Relaxation";
relax.default = (1,0);
relax.hint = "This can be used to slow down the convergence of the formula.";
scale1.caption = "Ring 1 Scale";
scale1.default = (1.0,1.0);
scale1.hint = "Sets the width and height of the ring used for the real axis, carved through z space.";
scale2.caption = "Ring 2 Scale";
scale2.default = (1.0,1.0);
scale2.hint = "Sets the width and height of the ring used for the imaginary axis, carved through c space.";